zakerna zahada GCC

Jindroush jindroush na seznam.cz
Středa Únor 7 21:11:40 CET 2018


Je mozno si to vyzkouset:
https://godbolt.org/
x86-64, -m32 -O99 -Wall

#include <cstdlib>

char  text[19];
char text2[19];

int main()
{
   for( size_t idx = 0; text[idx]!=0 && idx < sizeof( text ); idx++)
   {
     text2[idx]=text[idx];
   }
}

Opravdu tu druhou podminku eliminuje a uplne tomu vysvetleni nerozumim.
Kdyby idx<sizeof(text) bylo vzdy true, tak bych tomu rozumel. Protoze 
podle normy idx smi legalne nabyvat pouze hodnot mezi 0 az 
sizeof(text)-1, tak skutecne podminka je vzdy true a smi se eliminovat.
Ale to by prece platilo i pro ten opacny pripad, kdy ji napisu jako prvni?

J.

On 7.2.2018 18:26, Jan Waclawek wrote:
> Kuzelne.
> 
> Dovod ste uviedli hned na zaciatku:
> 
>> Uz vim, ze je to v principu spatne a prvni cast si sahne mimo
>> rozsah pole, ale ze by to prekladac poresil takto?
> 
> Moze, pretoze nasledok je nedefinovane spravanie. A co nie je zakazane, je
> dovolene; a nerobit nieco, co netreba, je optimalne... ;-)
> 
> V tomto konkretnom pripade je to nasledok poslednej vety C99 6.5.6#8 (co
> spolu s nasledujucim odstavcom je definicia toho co bezne nazyvame
> smernikova aritmetika, a ktora je tu aplikovana vdaka tomu ze v C
> neexistuju polia, 6.5.2.1#2):
> 
> If the result points one past the last element of the array object, it
> shall not be used as the operand of a unary * operator that is evaluated.
> 
> (slovicko "shall" tu vedie kvoli 4#2 na nedefinovane spravanie)
> 
> To "one past" je taka kuriozita, ktora dovoluje smerniku nadobudat hodnotu
> 1 za polom. Tym sa dovoluje optimalizujuci postinkrement po pristupe k
> prvku pola v cykle. Nesmie sa samozrejme takyto smernik dereferencovat,
> ale moze sa pouzit napriklad na porovnanie alebo sa moze dekrementovat (co
> zase dovoluje predekrement pri opacnom cykle). (Musite samozrejme zabudnut
> na naivnu predstavu ze hodnota smernika *je* cislo, a uz vobec nie adresa.
> Moze byt, ale nemusi - a norma predpisuje vseobecne spravanie, nie nejaku
> jednu konkretnu implementaciu, co je vlastne zaruka portability. Moze to
> byt ciste hardwarovo implementovane, s hardwarovou implementaciou ochran
> proti vylezeniu z pola. Do urcitej obmedzenej miery nieco take MMU vlastne
> robi.).
> 
> Bezne ukazanie niekam uplne mimo pola vseobecne riesi popis operatora * v
> 6.5.3.2#4:
> If an invalid value has been assigned to the pointer, the behavior of the
> unary * operator is undefined.
> 
> Mimochodom, zaujimalo by ma, ci bol vypisany nejaky suvisiaci warning,
> najma v suvislosti s -Warray-bounds (pripadne ak sa jedna o novsiu veriu
> gcc, tak -Warray-bounds=2
> https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Warning-Options.html#index-Warray-bounds
> )
> 
> wek
> 
> 
> PS.
>> definuj text[19] ako volatile,
> Nie, to tu nemusi pomoct, lebo pre tuto "optimalizaciu" prekladac
> nepotrebuje poznat *hodnotu* prvku z pola, kedze vopred *vie*, ze citanie
> z nej ma nedefinovany nasledok, pretoze to uz nie je prvok pola.
> 
> *Moze* to pomoct, lebo sa bavime o nedefinovanom spravani, ale nemusi.
> 
> Ale mas pravdu, vhodne nastavene volatile pomoze: celkom iste pomoze
> kvalifikovat idx ako volatile, pretoze vtedy prekladac nemoze vediet, aku
> hodnotu ma idx na zaciatku toho porovnania, a teda akakolvek
> "nedefinovanost" spravania je mimo moznosti detekcie kompilatorom a je
> dana uz len konkretnym hardwarom, na ktorom to pobezi.
> 
> 
> 
>> Am 07.02.2018 um 17:09 schrieb Jaroslav Buchta:
>>> Me jde o pripad, kdy je leva podminka splnena a idx uz ma hodnotu
>>> treba 19, 20... coz podminku nesplnuje (pokud jsem neco neprehlednul)
>>> a iterace se provede. Dle disassebleru neni druha cast podminky vubec
>>> zohlednena, testuje se jen znak v retezci na 0.
>>> Kopirovani tady musim provadet po znaku, pridavaji se do dynamicky
>>> alokovaneho pole s nejakou inteligenci a tady neni kvalt.
>>> S dosazenim funkcnosti si poradim, spis si to potrebuju vysvetlit,
>>> tento problem se muze vyskytnout i jindy a jinde.
>>>
>>> Dne 07.02.2018 v 16:15 Jindroush napsal(a):
>>>> Dobry den,
>>>> nejsem si ted jist, jestli jsem pochopil spravne problem, ale podle
>>>> mne mluvite o vlastnosti C, tj. short-circuitingu AND operatoru.
>>>> Staci vyhodnotit levou cast a jde se dal, na poradi podminek zalezi.
>>>> To je dulezite si uvedomit i u funkci, ktere maji vedlejsi efekty.
>>>>
>>>> Jinak ten vas kod nezaruci zero-termination, nebo ano?
>>>>
>>>> Fungovat v debugu by to nemelo, jen to nesletelo, protoze tam byla
>>>> jinak a jinde alokovana pamet.
>>>>
>>>> Co vam brani pouzit bezpecnou knihovni alternativu - strlcpy?
>>>> (Pripadne ji nekde obslehnout).
>>>>
>>>> J.
>>>>
>>>> On 7.2.2018 14:56, Jaroslav Buchta wrote:
>>>>> Mam datovy typ:
>>>>>
>>>>> typedef union
>>>>> {
>>>>>       struct {
>>>>>           uint8_t b[32];
>>>>>       } ba;
>>>>>
>>>>>       struct {    //common all records (chained records exception)
>>>>>           uint32_t id;            // id MSb == 0
>>>>>           uint32_t tstp[2];
>>>>>       }cmn;
>>>>>
>>>>>       struct {    //Text Single or Start Record
>>>>>           uint32_t id;            // id MSb == 0
>>>>>           uint32_t tstp[2];        //timestamp in miliseconds, record
>>>>> type FLCLOG_RT_* at 4 MSbs
>>>>>           uint8_t  sendRq;        //send to server request
>>>>>           uint8_t  text[19];    //content, max length
>>>>>       }recTxt;
>>>>>
>>>>> ...
>>>>>
>>>>> }FLCLOGRECORD;
>>>>>
>>>>> Pokud napisu podminku
>>>>>
>>>>> for (int idx=0; rec.recTxt.text[idx] != 0 && idx <
>>>>> sizeof(rec.recTxt.text); idx++)
>>>>>
>>>>> tak se to vykasle na druhou cast a index klidne leze na 19 a vic
>>>>> dokud neni v pameti nahodou nula (kopiruje to strin ktery muze ale
>>>>> nemusi koncit 0) Uz vim, ze je to v principu spatne a prvni cast si
>>>>> sahne mimo rozsah pole, ale ze by to prekladac poresil takto?
>>>>>
>>>>> Kdyz podminky prehodim
>>>>>
>>>>> for (int idx=0; idx < sizeof(rec.recTxt.text) &&
>>>>> rec.recTxt.text[idx] != 0; idx++)
>>>>>
>>>>> Tak to funguje OK ale uz jsem nemel cas zkoumat disassembler. V
>>>>> neoptimalizovanem kodu to fungovalo i pro prvni variantu.
>>>>>
>>>>> Vysvetli to chovani nekdo?
>>>>>
> 
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list at list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
> 


-- 
Jindroush <jindroush at seznam.cz>


Další informace o konferenci Hw-list