Na, de miért?
while (isupper((unsigned char) p[j])) buff[j++] = p[j];
Az '=' operátor right to left asszociatív. Vagy dönthet a fordító úgy, hogy a magasabb precedenciájú kifejezéseket akármilyen sorrendben értékelteti ki futásidőben, s majd a részeredmények felhasználásával lesz az értékadás jobbról balra? Mert én úgy gondoltam, amikor ezt a sort leírtam, hogy előbb meghatározza p[j] értékét, majd utána ezt értékül adja buff[j]-nek, majd j-t növeli eggyel.
Ezt a warningot egyébként a Qt Creator zúdítja rám. Miért nem mcedit-tel írom a forráskódot? Akkor boldog tudatlanságban élhetnék... :)
- 154 megtekintés
Hozzászólások
>Ezt a warningot egyébként a Qt Creator zúdítja rám.
Nem a fordítóból veszi? Saját értelmezője és warningjai vannak? Nem hinném. Nézz utána, hogy milyen parancsot futtat, gondolom szigorúbb warningokat kér magától, mint ahogy te szoktad paraméterezni a fordítót.
IMHO ez a j++ indexben már önmagában is zavaró, én a falra mászok ezektől. Nálam ez így nézne ki: {buff[j] = p[j]; j++;} Minek terheljem az olvasót azzal, hogy akkor ez posztfix, tehát kiértékelés után lesz inkrementálva és satöbbi? Leírnám úgy ahogy történik sorban és kész. Ezeket már tényleg kibogozza a fordító optimálisra akárhogy is írod az ekvivalens kifejezéseket.
- A hozzászóláshoz be kell jelentkezni
Igazából az a kérdésem, hogy ez a sor egyértelmű a C-ben, vagy a fordítható fordíthatja-e úgy, hogy az értékadás bal oldalával foglalkozik előbb, ott inkrementálja az indexet, majd a jobb oldal ezt a növelt értéket használja. Szerintem ezt nem teheti a fordító - ebben tévedhetek -, egyértelműnek és jónak látom ezt a sort. Azokkal itt nem kívánok foglalkozni, akik kényszeresen kiteszik oda is a zárójelet, ahova nem kell, hátha a fordító rosszul emlékszik a precedenciára, és hasonlók. A mask << x + 4 is egyértelmű, de ha valaki zárójel fetisiszta, az írhatja felőlem, hogy mask << (x + 4), csak ne szaladjunk abba bele, hogy muszáj, mert biztos bugos a fordító, vagy annak a feje, aki olvassa a kódot.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
>Szerintem ezt nem teheti a fordító - ebben tévedhetek -, egyértelműnek és jónak látom ezt a sort.
>Azokkal itt nem kívánok foglalkozni, akik kényszeresen kiteszik oda is a zárójelet, ahova nem kell, hátha a fordító rosszul emlékszik a precedenciára, és hasonlók.
Az a baj, hogy aminek egyértelműnek kellene lenni szerinted - nevezetesen, hogy mi a kiértékelési sorrend - az a jelek szerint nem is egyértelmű a szabvány szerint. (Én se tudtam.) Ezért mondom, hogy mindenki sokkal jobban jár, ha sorba le van írva, hogy mit kell csinálni. Fel se merülne a probléma, ha az inkrementálás külön sorban lenne leírva úgy, ahogy ésszerű volna.
Persze a C nyelv egy trükkhalmaz, még akkor is megviccelheti az embert, ha mindent háromszor körüljár. De ésszerűbb legalább a triviális komplexitást elkerülni. Az olyanokat, mint például ez, hogy indexben inkrementáljuk a változót. Szép trükkös, ismerem én is az egysorosokat, de már nem írok le ilyeneket többé. Jobb a békesség.
- A hozzászóláshoz be kell jelentkezni
Az indexben inkrementálással nincs baj, itt a gond abból lehet, hogy ezt az indexet máshol is felhasználom, s kérdés, az még az inkrementálás előtt vagy után történik-e. Az asszociativitásból az jönne, hogy előbb, de valóban, ahogy NevemTeve írta is, lehet ezt úgy fordítani, hogy rossz legyen. Ugye, lehet ilyet is csinálni:
a = b = c = 5;
Ha nem lehetne használni az indexben inkrementálást, akkor felesleges lenne a pre- és postincrement. Azért van, hogy használjuk. Engem az lepett meg, hogy van arra esély, hogy ez úgy forduljon le, hogy rossz legyen.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
buff[j++] = p[j]
A derék fordító maga dönthet arról, hogy ebből mit generál:
#1:
char *tmp= &buff[j];
++j;
*tmp = p[j]
#2:
buff[j] = p[j];
++j;
- A hozzászóláshoz be kell jelentkezni
A jövőálló megoldás nyilván két index használata:
k= j;
while (isupper((unsigned char) p[j])) {
buff[k++] = p[j];
}
Ha mondjuk kiderül, hogy az elején lévő számjegyeket át kell lépni:
k= j;
while (isdigit((unsigned char) p[j])) ++j;
while (isupper((unsigned char) p[j])) {
buff[k++] = p[j];
}
- A hozzászóláshoz be kell jelentkezni
Mármint nem j, hanem j++.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Hát ebben van igazság, bocsi.
Így egymás közt azt is bevallhatom, hogy gyakran így csinálom a hasonlókat:
for (--j; isspace(from[++j]););
for (--j; ++j<limit && isdigit(from[j]); )
into[k++]= from[j]
- A hozzászóláshoz be kell jelentkezni
Itt lehet bővebben tájékozódni:
https://en.wikipedia.org/wiki/Sequence_point
- A hozzászóláshoz be kell jelentkezni
#1 egy reális veszély? Azért nyomasztó, mert néhány helyen használtam ilyesmit kódban, s elég kellemetlen nagyon sok tízezer sorban az összes ++-ra keresni, s egyesével átnézni. Abból indultam ki, hogy az értékadás miatt előbb lesz kiértékelve a jobb oldal, s csak utána a bal, mert ez a #2, s akkor jó a kód.
Szerk.: Abban lehet bízni, hogy egy adott fordító legalább következetesen #2-t fordítja minden hasonló esetben? Vagy kétségbeesetten kezdjem felkutatni azt a kevés helyet a jó nagy kódban, ahol ilyen van?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Vannak különféle checker/linter programok, például maga a gcc (latest: 15.1), különösen a -fanalyzer opcióval.
- A hozzászóláshoz be kell jelentkezni