Z Javy migrujuvší Cčkar 3.5: Sloboda, =, bratstvo

Kde bolo, tam bolo, bola raz jedna sociálna krajina, kde sa rozhodli odmeniť zbiedených.

Počnúc zajtrajšom, každý, kto nezarába nič, dostane 60 dukátov ako dar od štátu.

Ľud zabedákal, IT divízie sa zaradovali, lebo mohli vyhrať tender na systém pre výpočet dane. Vyhrala firma GCC s.r.o. s nasledovným kódom:

#include <stdio.h>
#include <stdlib.h>

#define SOCIALNA_DAVKA 60;

int ziskaj_mzdu(int mzda) {
    if(mzda = 0) {
        return SOCIALNA_DAVKA;
    } else {
        return mzda;
    }
}

int main()
{
    printf("Prijem pre pracujuceho: %d\n", ziskaj_mzdu(2000));
    printf("Prijem pre nepracujuceho: %d\n", ziskaj_mzdu(0));
    return EXIT_SUCCESS;
}

Systém zostavili, nasadili… a žiadny bezprijímový občan nedostal nič. Obyvatelia dva týždne revoltovali, zvrhli vladára, na jeho miesto nastúpil nový, ten vyhlásil nový tender na nový informačný systém (v Jave), a všetci žili šťastne až kým nepomreli.

Prečo GCC padla?

Na konštrukcie typu

if(mzda == 0)

si treba dávať veľký pozor. Ak prichádzate z iných jazykov, napríklad Pascalu, stáleho hitu stredných škôl, tak sa pokojne môže stať, že napíšete (beda!):

if(mzda = 0)

V Jave je to samozrejme kompilačná chyba, ale v C to vedie len k varovaniu. Čo sa stane?

  1. do premennej mzda sa priradí nula
  2. celý priraďovací príkaz sa vyhodnotí na hodnotu premennej mzda
  3. hodnota premennej mzda sa použije ako pravdivostná hodnota do ifu.

Na príklade:

if(mzda = 0)
     |||
     VVV
      V
    if(0)

čo znamená, že vnútro ifu sa nevykoná nikdy.

Ešte krajší je príklad

if(mzda = 1)

aleb

if(mzda = 2000)

ktorý sa (podobnou úvahou) vždy vyhodnotí na pravda˛.

Pokiaľ máte v gcc zapnuté varovania (buď -Wall alebo -Wparentheses), dodstanete takúto chybovú hlášku:

error: suggest parentheses around assignment used as truth value

Ešte ďalšie bedáky nad ifmi

Na hranici zvrhlosti je príklad:

int x = 20;
if(1 <= x <= 10) {
    printf("V intervale 1..10.");
}

Varovná hláška:

error: comparisons like 'X<=Y<=Z' do not have their mathematical meaning

Bez nej by sa to vyhodnotilo vždy na nepravda, keďže operátor <= je zľava asociatívny, platilo by

(1 <= x) <= 10
    1    <= 10
       1

Záver

Ako obvykle: zapínajte varovania! Hlavne ak ste začiatočníci!

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *