Notatnik techniczny

c++ Komentarze i inne pułapki

Pułapki c++

Poniższy kod jest niesamowicie skomplikowany. Czy ktoś z Was założyłby się o jego wynik? A może w tym kodzie jest coś podejrzanego, na co musimy zwrócić uwagę?

#include <iostream>
 
using namespace std;
 
int main() {
    int n = 10;
    //zgadnij jaka bedzie wartosc zmiennej n ???????????/
    n = 20;
    cout << "zmienna n = "<< n << endl;
    return 0;
}

Na pozór wszystko wydaje się oczywiste. Przecież nawet IDE (cLion) ostrzega, że pierwsze przypisanie n=10 jest niepotrzebne.

c++ komentarze

Przekonajmy się zatem sami. Ekran konsoli pokaże nam następujący wynik:

zmienna n = 10
 
Process finished with exit code 0

Zaskoczeni? To powiedzcie, co zatem zobaczymy na ekranie po uruchomieniu tego kodu c++? Zakładając oczywiście, że poprawnie się go skompiluje, bo IDE pokazuje, że nie ma on sensu.

#include <iostream>
#include <vector>
 
using namespace std;
 
int main() {
    vector<int> liczby = {1,2,3%>;
    liczby[1] xor_eq 11;
    cout << "??=??=??=  "<< liczby<:1??) << "  " << liczby??(2??) << endl;
    return 0;
}

c++ komentarze 2

Program skompiluje się poprawnie (MAGIA) i na ekranie zobaczymy:

###  9  3
 
Process finished with exit code 0

Wyjaśnienie zagadki

Ciekawi was, dlaczego tak się stało? Otóż w c++ mamy pewnie zbiór di-grafów oraz tri-grafów. Zostały one wprowadzone w zamierzchłych czasach, aby umożliwić kodowanie na klawiaturach niewyposażonych w niektóre znaki. Kompilator przetłumaczy te wyrażenia na przypisane im wartości, zanim przystąpi do właściwej analizy kodu.

Ponadto w wersji 14 wprowadzono pewne dodatkowe tokeny. Poniżej zestawienie dostępnych pułapek. Co bardzo ważne, poniższe znaki są konwertowane, nawet jeśli będą zapisane jako łańcuchy tekstowe. Komitet standaryzacyjny c++ przegłosował usuniecie trigraphs ze standardu w c++17.

Trigraph Wartość
??= #
??/ \
??’ ^
??( [
??) ]
??! |
??< {
??> }
??- ~
Digraph Wartość
<: [
:> ]
<% {
%> }
%: #
Token Wartość
%:%: ##
compl ~
not !
bitand &
bitor |
and &&
or ||
xor ^
and_eq &=
or_eq |=
xor_eq ^=
not_eq !=

W pierwszym przykładzie tri-graph ??/ został zamieniony na znak “\“, który to obecny na końcu komentarza powoduje jego kontynuację do następnej linii.