ARM-GCC warning

Vse o programiranju na in za PC

Moderatorji: Kroko, tilz0R

ARM-GCC warning

OdgovorNapisal/-a tilz0R » 22 Mar 2017, 09:30

Nevem, vedno sem imel odpor po GCC-ju (predvsem ARM GCC-ju) za osebne projekte.

Za spodnjo kodo...
Koda: Izberi vse
uint32_t BUFFER_GetFree(BUFFER_t* Buffer) {
   uint32_t size, in, out;
   
   in = Buffer->In;
   out = Buffer->Out;
   if (in == out) {
      size = Buffer->Size;
   }
   if (out > in) {
      size = out - in;
   }
   if (in > out) {
      size = Buffer->Size - (in - out);
   }
   return size - 1;
}

...dobim:
warning: 'size' may be used uninitialized in this function [-Wmaybe-uninitialized]


Uporabljen ni if-else, zato, ker s tem zgubiš determinizem funkcije, ampak pustimo to.

Zakaj je to GCC warning?

Prosim brez komentarjev v stilu "pa kaj boš jamral za 1 if-else če je determinizem ali ne!"

PS: ARM-CC in EWARM ne javljata ničesar, ker nimata kaj za jamrat.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a peterp » 22 Mar 2017, 10:29

tilz0R je napisal/-a:Zakaj je to GCC warning?
Verjetno statična analiza kode ne ugotovi, da se size v vsakem primeru nastavi. Zato pač javi ta warning.
peterp
 
Prispevkov: 657
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor
Zahvalil se je: 164 krat
Prejel zahvalo: 112 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 114

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 22 Mar 2017, 11:30

Verjetno eden od mnogih primerov, kjer ima gcc težave.
https://gcc.gnu.org/bugzilla/buglist.cg ... nitialized

Poskusi z optimizacijo -O0
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a peterp » 22 Mar 2017, 11:41

Kroko je napisal/-a:Verjetno eden od mnogih primerov, kjer ima gcc težave.
Verjetno odvisno od verzije, sistema in še kaj?
Ubuntu 16.04.2 LTS, gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) tega warninga ne javi.
peterp
 
Prispevkov: 657
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor
Zahvalil se je: 164 krat
Prejel zahvalo: 112 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 114

Re: ARM-GCC warning

OdgovorNapisal/-a forest70 » 22 Mar 2017, 12:05

Saj je jasno. imaš deklarirano
uint32_t size;
Če nobeden if ni izpolnjen, varjabili size ni bila nikoli dodeljena vrednost.
Vračaš se pa z:
return size - 1;
rešitev:
pri deklaraciji
uint32_t size=0;
If you pay in bananas, you got monkeys.
Uporabniški avatar
forest70
 
Prispevkov: 2151
Pridružen: 14 Jan 2015, 01:11
Kraj: Koper
Zahvalil se je: 411 krat
Prejel zahvalo: 457 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 122

Re: ARM-GCC warning

OdgovorNapisal/-a tilz0R » 22 Mar 2017, 12:06

forest70 je napisal/-a:Saj je jasno. imaš deklarirano
uint32_t size;
Če nobeden if ni izpolnjen, varjabili size ni bila nikoli dodeljena vrednost.
Vračaš se pa z:
return size - 1;

Ne vem če je jasno. Vidiš opcijo da ni nobeden izpolnjen?
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a forest70 » 22 Mar 2017, 12:13

tilz0R je napisal/-a:
forest70 je napisal/-a:Saj je jasno. imaš deklarirano
uint32_t size;
Če nobeden if ni izpolnjen, varjabili size ni bila nikoli dodeljena vrednost.
Vračaš se pa z:
return size - 1;

Ne vem če je jasno. Vidiš opcijo da ni nobeden izpolnjen?

Jaz to vidim, prevajalnik pa ne! Saj z worning-om ni nič narobe, samo te pozori na možnost, v izogib temu pa dodeliš vrednost variabili.
If you pay in bananas, you got monkeys.
Uporabniški avatar
forest70
 
Prispevkov: 2151
Pridružen: 14 Jan 2015, 01:11
Kraj: Koper
Zahvalil se je: 411 krat
Prejel zahvalo: 457 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 122

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 22 Mar 2017, 12:23

V bistvu morda res vidim opcijo, ko ni noben izpolnjen. Odvisno je od tega, kaj gcc dela v ozadju glede na nastavljeno stopnjo optimizacije.
Konkretno - ker in in out nista deklarirana kot volatile lahko gcc predvideva, da se njuna vrednost ne spreminja. To pomeni, da je po optimizaciji programski flow precej drugačen, kot si si zamislil in vrednost lahko ostane nedefinirana. Da bi gcc naredil tako, kot si predstavljaš bi moral imeti za tvoj primer narejeno izjemo, da bi optimizer delal kot si želiš. Bi pa na ta račun trpela hitrost.
Spremenjen flow postavi pod vprašaj tudi smiselnost determinizema. Ali si na račun determinizma pripravljen žrtvovati kar precej hitrosti?
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a zanka » 22 Mar 2017, 12:26

Kako pa se odzivajo drugi prevajalniki?
edit: Sem spregledal.

Mimogrede, če VEŠ, da drugih možnosti ni, uporabi else, s čimer se znebiš enega primerjanja. V tem primeru drugih množnosti res ni, saj velja zakon trihotomije.
Uporabniški avatar
zanka
 
Prispevkov: 2567
Pridružen: 17 Mar 2016, 01:16
Zahvalil se je: 113 krat
Prejel zahvalo: 254 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 50

Re: ARM-GCC warning

OdgovorNapisal/-a tilz0R » 22 Mar 2017, 12:32

Absolutno lahko namečen if-else in tudi bom ampak vseeno.

@Kroko
Ne razumem najboljše. Tudi če nista volatile, bi za moje pojme moral preveriti vsak del kode. Sicer je volatile rešil problem, ampak za moje pojme tukaj volatile nikakor ne sme vplivati. Ne vem, ni mi čisto jasno zakaj bi volatile vplival v tem primeru.

Če prvi if stavek faila, to ne pomeni da ne potrebuje it pregledat ostalih dveh.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 22 Mar 2017, 13:57

Daj poskusi originalen primer z različnimi stopnjami optimizacije in poročaj. Bom potem razložil zakaj je tako.

V bistvu je to skoraj šolski primer uporabe volatile. Upoštevaj, da tvojo kodo prežveči še optimizer.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a tilz0R » 22 Mar 2017, 14:03

Sej, če ni optimizacije ni warninga, če je volatile tudi ni warninga. Samo ne vidim šolskega primera.
Interesanten primer.

Razumem da bo optimizator vrgel ven takšno kodo
Koda: Izberi vse
int a = 5;
while (a--);

Ker ni nekega smisla v njej, da loopaš in nič z A-jem ne počneš.

Samo 3 if stavki, ki med seboj nimajo povezave in nikakor ne smejo ven letet? Zanimivo.

Edit:
Vbistvu sem pozabil, da imam 2 funkciji, s enakimi forami v isti datoteki
Koda: Izberi vse
uint32_t TM_BUFFER_GetFree(TM_BUFFER_t* Buffer) {
   uint32_t size, in, out;
   
   /* Check buffer structure */
   if (Buffer == NULL) {
      return 0;
   }
   
   /* Save values */
   in = Buffer->In;
   out = Buffer->Out;
   
   /* Check if the same */
   if (in == out) {
      size = Buffer->Size;
   }

   /* Check normal mode */
   if (out > in) {
      size = out - in;
   }
   
   /* Check if overflow mode */
   if (in > out) {
      size = Buffer->Size - (in - out);
   }
   
   /* Return free memory */
   return size - 1;
}

uint32_t TM_BUFFER_GetFull(TM_BUFFER_t* Buffer) {
   uint32_t in, out, size;
   
   /* Check buffer structure */
   if (Buffer == NULL) {
      return 0;
   }
   
   /* Save values */
   in = Buffer->In;
   out = Buffer->Out;
   
   /* Pointer are same? */
   if (in == out) {
      size = 0;
   }
   
   /* Check pointers and return values */
   /* Buffer is not in overflow mode */
   if (in > out) {
      size = in - out;
   }
   
   /* Buffer is in overflow mode */
   if (out > in) {
      size = Buffer->Size - (out - in);
   }
   
   /* Return number of elements in buffer */
   return size;
}


Warning pri prevajanju datoteke. Torej javi samo pri eni funkciji, pri drugi pa ne.
Koda: Izberi vse
arm-none-eabi-gcc -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 '-D__weak=__attribute__((weak))' '-D__packed=__attribute__((__packed__))' -DUSE_HAL_DRIVER -DSTM32F746xx -DSTM32F7xx -DSTM32F7_DISCOVERY -I"Inc" -ILegacy -IInclude -IInclude -I"00-STM32_LIBRARIES"  -Os -g3 -Wall -fmessage-length=0 -ffunction-sections -c -fmessage-length=0 -MMD -MP -MF"tm_stm32_buffer.d" -MT"tm_stm32_buffer.o" -o "tm_stm32_buffer.o" "tm_stm32_buffer.c"
tm_stm32_buffer.c: In function 'TM_BUFFER_GetFree':
tm_stm32_buffer.c:343:9: warning: 'size' may be used uninitialized in this function [-Wmaybe-uninitialized]
  return size - 1;


Kako pa je to možno?
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 22 Mar 2017, 18:34

Ali sta Buffer->In in Buffer->Out deklarirana kot volatile?
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a tilz0R » 22 Mar 2017, 18:47

Nobeden.

Koda: Izberi vse
/**
 * @brief  Buffer structure
 */
typedef struct _TM_BUFFER_t {
   uint16_t Size;           /*!< Size of buffer in units of bytes, DO NOT MOVE OFFSET, 0 */
   uint16_t In;             /*!< Input pointer to save next value, DO NOT MOVE OFFSET, 1 */
   uint16_t Out;            /*!< Output pointer to read next value, DO NOT MOVE OFFSET, 2 */
   uint8_t* Buffer;         /*!< Pointer to buffer data array, DO NOT MOVE OFFSET, 3 */
   uint8_t Flags;           /*!< Flags for buffer, DO NOT MOVE OFFSET, 4 */
   uint8_t StringDelimiter; /*!< Character for string delimiter when reading from buffer as string, DO NOT MOVE OFFSET, 5 */
   void* UserParameters;    /*!< Pointer to user value if needed */
} TM_BUFFER_t;
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a peterp » 23 Mar 2017, 12:29

A smo s tem problemom zaključili? Vseeno bi bilo dobro še kaj napisati na to temo :_helpsos
peterp
 
Prispevkov: 657
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor
Zahvalil se je: 164 krat
Prejel zahvalo: 112 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 114

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 23 Mar 2017, 16:43

Celo trije scenariji, ki opravičujejo ta warning, obstajajo.

1. Recimo, da optimizer ven vrže tole:
in = Buffer->In;
out = Buffer->Out;
to lahko naredi saj in in out nista deklarirana kot volatile.
Nadalje Buffer->In in Buffer->Out optimizer obravnava kot da sta volatile. Zaradi tega ne optimizira if pogoja ampak dejansko predpostavlja, da se njuna vrednost lahko spremeni.
Če pa se vrednost spremeni potem bo na koncu size nedefiniran.

Če je ta scenarij malce "za lase privlečen" so drugi povsem realni (no, mogoče v kakšnem malce drugačnem svetu).

2. uint16_t je definiran šele v C99 standardu. Pa tudi če imaš specificirano, da prevajalnik uporablja C99 standard, je lahko uint16_t nastavljen na half.

3. Taka koda ni portabilna. Lahko obstajajo platforme na katerih vsi trije if-i vrnejo false. Tako, kot če bi namesto uint16_t uporabil double.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a tilz0R » 23 Mar 2017, 16:51

Za uint16_t imam sledece.

Typedef unsigned short uint16_t

Torej to ne verjamem da ima veze z C99, ali se motim?
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 23 Mar 2017, 16:57

Ti imaš tako, jaz pa imam lahko drugače. Prevajalnik je samo opozoril na možno skrito napako.

Če nimaš določeno da uporabljaš C99 standard potem imam jaz lahko celo takole:
typedef double uint16_t
In nič ni s tem narobe.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a tilz0R » 23 Mar 2017, 16:58

To se strinjam. Situacija je zelo zanimiva.

Samo warning je vrnil samo v enem primeru. Pri drugi funociji ga ni.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1814
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a Kroko » 23 Mar 2017, 17:01

Vprašanje, kaj je naredil optimizer. Ker optimizacija je na vrsti pred prevajanjem.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4771
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1647 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM-GCC warning

OdgovorNapisal/-a peterp » 23 Mar 2017, 18:49

Kroko je napisal/-a:1. Recimo, da optimizer ven vrže tole:
in = Buffer->In;
out = Buffer->Out;
to lahko naredi saj in in out nista deklarirana kot volatile.
Sprašujem se zakaj bi to odstranil? Kakšen je razlog?
peterp
 
Prispevkov: 657
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor
Zahvalil se je: 164 krat
Prejel zahvalo: 112 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 114

Re: ARM-GCC warning

OdgovorNapisal/-a MitjaN » 23 Mar 2017, 22:17

SIcer mi ni popolnoma jasno, kdaj dobiš to opzorilo. Ko imaš vklopljeno optimizacijo ali ko je izklopljena?

V primeru vklopljene optimizacije je lahko razlog v tem, da optimizator združi prvi in tretnji stavek if. Drugi stavek if je pa tako preprost, da ga lahko gre delati z pogojnim "move" ukazom, če ga arhitektura podpira. In ravno ta pogojni "move" lahko "zmede" prevajalnik, da ti sporoči opozorilo.

Po mojih izkušnjah so prevajalniki v zadnjih letih precej napredovali, vendar kar se statične analize tiče, še vedno niso na nivoju namenskih orodji.
MitjaN
 
Prispevkov: 85
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 10 krat
Prejel zahvalo: 35 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 7


Vrni se na Programski jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost