2017-01-05 7 views
7

Czytam książkę o programowaniu C "Zaawansowane programowanie w środowisku Unix" oraz w "UNIX Standaryzacji i Wdrożeń" rozdział pokazuje program, który drukuje wartości dla symboli w sysconf i pathconf, kod w ten program ma kilka linii, które wygląda następująco:Zdefiniowane stałe jako argument formatu printf, dlaczego dodano "+ 0"?

#ifdef ARG_MAX 
    printf ("ARG_MAX defined to be %ld\n", (long) ARG_MAX + 0); 
#else 
    printf ("no symbol for ARG_MAX\n"); 
#endif 

Ilekroć zdefiniowana stała jest używana jako argument za printf to zawsze następuje + 0, nie wydaje się robić nic, bo starałem się go usunąć i nic się nie stało. Jaki jest sens dodawania zera?

+2

mogę myśleć o dwóch ogólnych zastosowań coś takiego, ale nie wydaje się być przydatna tutaj: 1) do wywoływania integralnej promocji, i 2) do tworzenia wartości wyrażenia (nie jest to l-wartość). –

+6

Mogę wymyślić inny: Jeśli masz '#define ARG_MAX', rozwija się do' (long) + 0' (tj. '0L'). Nie wiem, jak to by było możliwe (lub dlaczego chciałbyś go zaspokoić). – melpomene

+0

Które wydanie tej książki czytasz?Pierwotnie został napisany w 1992 roku, kiedy wiele aspektów C, Unix i POSIX było słabo zdefiniowanych lub słabo przestrzeganych. To pewnie ochrona przed jakąś dziwną implementacją, ale nie potrafię sobie wyobrazić. – Schwern

Odpowiedz

9

Pusty #define wymieniany przez melpomene w comment jest przyczyną użycia sztuczki + 0.

Jeśli jakiś nagłówek ma wartość #define ARG_MAX (bez wartości) - nieprawdopodobny, ale nie niemożliwy stan rzeczy - kod nadal będzie się kompilował, ale niezależnie od tego, czy dane wyjściowe są przydatne, to osobna dyskusja. Pusty zamiennik dla ARG_MAX pozostawia niezmieniony numer (long) + 0. Jeśli, jak można się spodziewać, definicja jest odpowiednio chronionym wyrażeniem (prawdopodobnie w nawiasach), dodanie wartości 0 nie powoduje zmiany wartości.

W normalnym toku wydarzeń, gdy preprocesor ocenia wyrażenie warunkowe, wszelkie identyfikatory pozostały po rozwinięciu makra są odwzorowywane na zero (ISO/IEC 9899: 2011 §6.10.1 warunkowego włączenia):

¶4 ... Po wykonaniu wszystkich operacji wymiany z powodu rozszerzenia makr i wykonania operatora defined, wszystkie pozostałe identyfikatory (w tym leksykalnie identyczne ze słowami kluczowymi) zostaną zastąpione przez numer pp 0, a następnie każdy token przetworzenia zostanie przekonwertowany do tokena. ...

Mimo, że nie jest bezpośrednio istotne dla tej kwestii, to jest dlaczego czasami zobaczyć wyrażenie warunkowe, takie jak:

#if ARG_MAX + 0 > 131072 
0

Dzieje się tak dlatego, że kod jest automatycznie generowany z programu awk.

Program awk (1) przedstawiony na rysunku 2.12 tworzy program C, który wypisuje wartość każdego symbolu pathconf i sysconf.

Ważną częścią programu jest to.

while (getline <"sysconf.sym" > 0) { 
    printf("#ifdef %s\n", $1) 
    printf("\tprintf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1) 
    printf("#else\n") 
    printf("\tprintf(\"no symbol for %s\\n\");\n", $1) 
    printf("#endif\n") 
    printf("#ifdef %s\n", $2) 
    printf("\tpr_sysconf(\"%s =\", %s);\n", $1, $2) 
    printf("#else\n") 
    printf("\tprintf(\"no symbol for %s\\n\");\n", $2) 
    printf("#endif\n") 
} 

Ponieważ nie wiem, co może zawierać symbol, to prawdopodobnie jest obronny o tym, że książka nie wyjaśnia, co jej obronie przeciw.

+1

Nie jestem pewien, czy odpowiada na pytanie. '+ 0' jest w kodzie C, ponieważ jest w kodzie awk - ale dlaczego jest w kodzie awk? –

+0

@ KeeThompson Tak, to nie jest odpowiedź, ale jest to ważny utwór. Reszta książki nie wydaje się używać '+ 0'. Zgaduję, że jest tam, aby zapobiec segfaultowi, jeśli wartość jest czymś dziwnym, ale nie wiem, jaka może być ta wartość. – Schwern

+0

Więc może byłoby lepiej jako komentarz. –

Powiązane problemy