goto statement

Język C++ udostępnia stosowanie dyrektywy goto realizującej skok bezwarunkowy do wskazanego miejsca w kodzie. We wpisie dotyczącym paradygmatów programowania wskazałem, że według paradygmatu programowania strukturalnego jest to dyrektywa wysoce odradzana.

Kod maszynowy

C++ jest językiem kompilowanym do kodu maszynowego procesora. Zadaniem kompilatora jest tłumaczenie języka wysokiego poziomu do języka niskiego poziomu. W tym miejscu kompilator ma dowolność w stosowaniu rozkazów procesora, również instrukcji skoków. O ile instrukcje typu IF, FOR czy WHILE wprost nie umożliwiają ustawienia miejsca docelowego instrukcji skoku (możliwe jest określenie bloku instrukcji do wykonania), to instrukcja SWITCH umożliwia ustawienie takiego miejsca jednocześnie nie ograniczając swobody programisty.

use of goto is bad idea

switch case jak goto

Przyjrzyjmy się następującemu programowi:

#include <cstdio>

int check_switch(const int value) {
    printf("value: %i\n", value);

    switch(value) {
        case 0:
        printf("    case 0\n");
        if ( value % 2 == 0 ) {
            case 1:
            printf("    value is even\n");
        } else {
            case 2:
            printf("    value is odd\n");
        }
        break;

        default:
        printf("    case default\n");
        break;
    }

    return value;
}

int main() {
    check_switch(0);
    check_switch(1);
    check_switch(2);
    check_switch(3);
    return 0;
}

Wynikiem wykonania programu będzie następujący komunikat:

value: 0
    case 0
    value is even
value: 1
    value is even
value: 2
    value is odd
value: 3
    case default

Powyższy kod (funkcja check_switch()) może zostać przedstawiony na następującej formie1:

Wygenerowano przy pomocy projektu gcc-uml

Co w tym kodzie jest wyjątkowego? Otóż dyrektywy case 1: oraz case 2: zostały umieszczone wewnątrz bloku IF (instrukcji warunkowej), co może wydawać się nietuzinkowym rozwiązaniem, dodatkowo powodującym błędne działanie programu (komunikaty niezgodne z zadanymi wartościami).

Co robić, jak żyć?

Nie często zdarza się, aby dyrektywa switch była używana w taki sposób. Niemniej, program cppcheck nie rozpoznaje tego typu niestandardowego użycia, zatem nie pozostaje nic innego jak zaktualizować w zespole reguły dotyczące kodu.

  1. diagram został wygenerowany z wykorzystaniem wewnętrznej reprezentacji kompilatora GCC ↩︎

Twój zespół potrzebuje wsparcia we wdrożeniu dobrych praktyk?


Leave a Reply

Your email address will not be published. Required fields are marked *