Re: C: co lze očekávat

Josef Štengl ok1ced na nagano.cz
Pondělí Srpen 29 17:17:00 CEST 2016


Problém je, že jste použil konstrukci, kterou překladače mohou (a dělají to tak) interpretovat různě jak se vývojáři 
překladače hodí. Není to chyba překladače (z hlediska vývojáře překladače), ale vaše :-)

Problém:
1) Používáte char bez toho aby jste striktně definoval jestli je signed nebo unsigned a předpokládáte že má velikost 8 
bitů, jak již psal Láďa.

2) Používáte char pro čísla. Není to ani tak špatně, jako 20 let nevhodná a nedoporučovaná konstrukce. Nevěřím, že kód je 
15 a více let starý. Používat by měly primárně typy definované v stdint.h a inttypes.h. Nemusíte, ale pak se pak nedivte 
:-). On by se char měl používat pouze na znaky (pouze char bez signed/unsigned), tam je jedno jestli je znaménkový či nikoliv.

3) spoléháte se na over/under flow u proměnných. V C! Jaká to drzost! :-D
To je cesta na psychiatrii, zejména při zapnuté optimalizaci. Čím více optimalizace, tím větší pravděpodobnost, že vám v 
těchto případech nebudou předpokládaným (a bez optimalizace funkční) pracovat podmínky a cykly. A taky indexy pole, jak je 
vidět. C prostě nepředpokládá, že proměnné přetékají předpokládaným způsobem. Kdyby ano, tak by asi nikdo nenapsal 
kompilátor bez integrované věštecké koule.

Pes je zakopaný v tom, že C sebou vleče velkou historickou závislost a obecnost na HW tam kde to jde. Možná vás překvapí, 
že znaménkové integery (možné uložení) jsou definovány 3 možnými vzájemně nekompatibilními způsoby na . Nemá se pracovat tak 
jak dovolí, ale tak jak je jednoznačně definováno. Je to mrcha jedna panovačná a vyžaduje disciplínu a řádné vedení aby se 
necukala na každém řádku. :-)

Předpoklad, že stejný kód bude dávat stejný výsledek je jen a pouze v případě, že nezměníte ani kompilační prostředí ani 
řádku kódu. Cokoliv změníte, zejména kompilátor (a pro gcc i patchverzi, autoři jsou tím známý), můžete dostat jiný výsledek.

Prostě jste narazil, že jste předpokládal to co jiný považovali za nedůležitou zvyklost. To se stává. Hledá se to dost 
nepříjemně, také jsem si tím prošel.

Pokud bude čas a chuť doporučuji si najít na netu něco o coding rules, ale ty s vysvětlením proč. Když jsem si přečetl 
něco o bitových polích, přestal jsem je používat (tedy téměř :-). Pak vám C bude připadat jak cesta minovým polem kde krok 
vedle .... Prostě je to pro dané účely fajn jazyk a mám ho rád. Je takový ... svobodomyslný, nic vám nenutí jen říká kdy 
se bude chovat mravně a jinak si bude dělat co chce. :-D

@ ano souhlasím, jiný než dvojkový doplněk jsem v reálu neviděl (ale toho co jsem neviděl je přehršel :-)

Dne 29.8.2016 v 15:02 Miroslav Draxal napsal(a):
> Teď to chápu. Ale stejně je někde zakopaný pes. Jsem to napsal teď do  Michrochipu. Mel jsem dlouho odladěnou knihovnu pro obsluhu SPI. Linkuji ji do mnoha projektů. Aniž bych cokoli řešil, tak se odesílaný buffer ukládal v oblasti 0x00 ~ 0xff. A tam to prostě přeteče a výsledek je, při přetečení ukazuje vždy v rozsahu 0x00 ~ 0xff. Teď jsem do jednoho projektu, který chodí asi 3 roky bez chyb dodělával takovou blbost, a najednou to nechodilo. A tak jsem 3 dny hledal chybu všude možně, jenom ne v té odladěné knihovně SPI. Pak už jsem to celé honil v ASM. A tam jsem našel, že si tentokrát buffer pro SPI uložil na adresu 0x123 a tam to pak přeteklo na tu 0x234. Takže bych očekával, že stejný kód bude produkovat stejně přeložený ASM ať si to proměnné uloží kamkoli.
>
> Ten char je unsigned.
>
> -----Original Message-----
> From: Hw-list [mailto:hw-list-bounces na list.hw.cz] On Behalf Of Ladislav Vaiz
> Sent: Monday, August 29, 2016 1:28 PM
> To: HW-news
> Subject: Re: C: co lze očekávat
>
> Pozor, v článku se řeší pointer, zde jen char.
> Je ten char signed nebo unsigned? Podle toho se liší výsledek výrazu x + 1.
> 1 je int, takže se x převede na int a sečte s 1.
>
>
> #include <stdio.h>
> int main(){
>
>      char x = 0;
>      x--;
>
>      printf("%d\n", ((unsigned char)x) + 1); // 256
>      printf("%d\n", ((signed char)x) + 1); // 0
>
>      return 0;
> }
>
> L.
>
>
> Jindroush napsal(a):
>> Proste ukazovat pointerem mimo objekt a pak nad nim delat aritmetiku
>> je nedefinovane chovani. Reseni neni rozcilovani, ale uprava kodu tak,
>> aby dochazelo jen k definovanemu chovani.
>> J.
>>
>> On 29.8.2016 12:53, Miroslav Draxal wrote:
>>>
>>> Je to hodně zjednodušené, to x se používá v programu. Nějak nerozumím
>>> tomu, že si kompilátátor může dělat co chce. Je to char, obsahuje
>>> hodnotu 0xff, po odečtení musí přetéct do nuly.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> *From:* Hw-list [mailto:hw-list-bounces na list.hw.cz] *On Behalf Of
>>> *Jindroush
>>> *Sent:* Monday, August 29, 2016 12:35 PM
>>> *To:* HW-news
>>> *Subject:* Re: C: co lze očekávat
>>>
>>>
>>>
>>> Asi prijdu s Wekem po funuse, ale obecne je to x-- undefined
>>> behaviour a kompilator muze delat, co chce ;-)
>>>
>>> http://stackoverflow.com/questions/18186987/decrementing-a-pointer-ou
>>> t-of-bounds-incrementing-it-into-bounds
>>> i s odkazy na c99
>>>
>>> On 29.8.2016 12:22, Miroslav Draxal wrote:
>>>
>>>      Dobrý den,
>>>
>>>      Minulý týden jsem zde dával report o pnou předpokládané chybě c
>>>      XC8. Nějak v tom tápe i Michrochip. Mám dojem, že na tam mají
>>>      zaměstnaného studenta, který filtruje zprávy. Jednou píše že je
>>>      to OK, jednou že je to chyba. Co na to zdejší odborníci na C. O
>>>      co jde.
>>>
>>>
>>>
>>>      Mějme následující kód.
>>>
>>>
>>>
>>>      char arrayA[3]@0x123;
>>>
>>>      char x;
>>>
>>>      x = 0;
>>>
>>>
>>>
>>>          x--; // x=0xff
>>>
>>>          if ( arrayA[x + 1]) {……..}
>>>
>>>
>>>
>>>      z jaké adresy má brát if prvek z pole array? Jedná se mi o ten
>>>      konstrukt x+1. X je char, čili přeteče na 0x00. Má ukazovat na
>>>      0x123 nebo má brát konstrukt arrayA[x + 1]) přetečení a ukazovat
>>>      na 0x223?
>>>
>>>
>>>
>>>      U XC8 to teď to je tak, že pokud je array uloženo na 0x023 tak
>>>      toto ukazuje na adresu 0x023 a pokud je array uloženo na 0x123
>>>      tak to ukazuje na adresu 0x223.
>>>
>>>
>>>
>>>      Jak to tedy je?
>>>
>>>
>>>
>>> --
>>> Jindroush <jindroush na seznam.cz> <mailto:jindroush na seznam.cz>
>>>
>>>
>>> _______________________________________________
>>> HW-list mailing list  -  sponsored by www.HW.cz Hw-list na list.hw.cz
>>> http://list.hw.cz/mailman/listinfo/hw-list
>>>
>>
>>
>>
>> --
>> Jindroush <jindroush na seznam.cz>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> HW-list mailing list  -  sponsored by www.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
>>
>
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
>


Další informace o konferenci Hw-list