2017-05-14 60 views
5

Myślałem, że zarówno cpp foo.c i gcc -E foo.c do preprocess pliku źródłowego w ten sam sposób, ale mam ich dane wyjściowe różnią się dla tego samego pliku.Różnica między cpp i gcc -E

$ cat foo.c 
#define VARIABLE 3 
#define PASTER(x,y) x ## _ ## y 
#define EVALUATOR(x,y) PASTER(x,y) 
#define NAME(fun) EVALUATOR(fun, VARIABLE) 

extern void NAME(mine); 

Wynik dla cpp:

$ cpp foo.c 
# 1 "foo.c" 
# 1 "<built-in>" 1 
# 1 "<built-in>" 3 
# 329 "<built-in>" 3 
# 1 "<command line>" 1 
# 1 "<built-in>" 2 
# 1 "foo.c" 2 





extern void mine ## _ ## 3; 

$ 

Wynik dla gcc -E i clang -E:

$ gcc -E foo.c 
# 1 "foo.c" 
# 1 "<built-in>" 1 
# 1 "<built-in>" 3 
# 330 "<built-in>" 3 
# 1 "<command line>" 1 
# 1 "<built-in>" 2 
# 1 "foo.c" 2 





extern void mine_3; 
$ 

Dlaczego te wyjścia są różne, i które należy użyć, gdy chcę zobaczyć wstępnie przetworzone źródło?

kod oryginalny here

+0

Po prostu próbowałem tego. Moja wersja 'cpp' daje identyczne wyjście jak' gcc -E'. To samo, co wyjście 'gcc'. – selbie

+2

Otrzymuję takie same wyniki z 'cpp foo.c' jak z' gcc -E foo.c'. Czy możesz wkleić dane wyjściowe z 'cpp -v foo.c' do pytania? –

+1

Jeśli użyję '--traditional-cpp' jako parametru wiersza poleceń do cpp, otrzymam taki sam wynik jak twój. Wygląda na to, że ktoś już to rozpoznał jako prawdopodobną odpowiedź. – selbie

Odpowiedz

2

Różnica między nimi jest, że gcc -E wyeliminuje -traditional-cpp. Jeśli podasz tę opcję, powinieneś otrzymać taki sam wynik, jak cpp.

https://gcc.gnu.org/onlinedocs/cpp/Traditional-Mode.html

+0

Rzeczywiście. W jaki sposób gcc może wyeliminować tę opcję, ponieważ nie ma '-no-traditional-cpp'? – Bilow

+0

Wygląda na to, że niektóre programy 'cpp' (takie jak na mojej stacji roboczej) są budowane tak, aby nie były domyślne dla' -traditional-cpp'. Więc jeśli chcesz wyłączyć tryb tradycyjny podczas wywoływania 'cpp', jakikolwiek pomysł jak to zrobić? Moja wersja narzeka, jeśli spróbuję użyć '-no-traditional-cpp' lub' --no-traditional-cpp'. Jest to dla mnie akademickie, ponieważ wywołanie 'gcc -E' zamiast tego działa. –

+0

@Bow: 'gcc' zwykle eliminuje je, chyba że podano inaczej. –