Jste zde

Ještě jednou a lépe: proměnná jménem flag

Dnes se podíváme na používání proměnné s nepříliš popisným názvem: flag.

Původní kód

Pravidelně se setkávám s kódem, který používá booleovskou proměnnou pojmenovanou flag. Příklady:

Řídicí proměnná cyklu:

bool flag;
do {
    flag = false;
 
    // ...
    flag |= someAction1();
    flag |= someAction2();
    flag |= someAction3();
    // ...
} while (flag);

Parametr funkce:

void func(/* ostatní parametry */, bool flag) {
    // ...
}

Pojmenování návratové hodnoty z funkce:

bool flag = someFunc();
if (flag) {
    // ...
}

Proč takto ne?

Jméno flag neříká nic o významu proměnné. Místo toho, aby použití dané proměnné kód učinilo čitelnějším, stane se pravý opak.

Přemýšlel jsem nad tím, proč toto jméno tolik programátorů používá, a uvědomil jsem si, že v průběhu studia jsem takto pojmenovanou proměnnou v několika předmětech viděl použitou (např. algoritmy). Většinou je myšlenka takováto: "budeme provádět určitou akci, dokud není nastaven příznak". To je samozřejmě v pořádku. Je ale vhodné onen příznak pojmenovat inteligentněji, než flag (doslovný překlad slova "příznak").

Jako reálný příklad se naskýtá např. funkce siginterrupt, jejíž signatura bývá následující (včetně pojmenování parametru):

int siginterrupt(int sig, int flag);

Z dokumentace: If the flag argument is false (0), then ... If the flag argument is true (1) ...

Jak to udělat lépe?

Buď se použití podobných proměnných úplně vyhnout, nebo je alespoň vhodně pojmenovat. Příklady:

Řídicí proměnná cyklu:

bool somethingPrinted;
do {
    somethingPrinted = false;
 
    // ...
    somethingPrinted |= someAction1();
    somethingPrinted |= someAction2();
    somethingPrinted |= someAction3();
    // ...
} while (somethingPrinted);

Parametr funkce:

void func(/* ostatní parametry */, bool followSymlinks) {
    // ...
}

Pojmenování návratové hodnoty z funkce:

bool hasAlreadyBeenRenamed = someFunc();
if (hasAlreadyBeenRenamed) {
    // ...
}

Přidat komentář