The best source would be the C Standard:
C Draft Standards
In the C99 Draft look at 6.2.5 "Types" and 6.7.2 "Type specifiers".
Bye, Andreas
The best source would be the C Standard:
C Draft Standards
In the C99 Draft look at 6.2.5 "Types" and 6.7.2 "Type specifiers".
Bye, Andreas
Ok. if we have the code...
I think the expansionCode:#include<stdio.h> #define N = 10 #define INC(x) x+1 #define SUB(x,y) x-y #define SQR(x) ( (x) * (x) ) #define CUBE(x) (SQR(x) * (x) ) #define M1(x,y) x##y #define M2(x,y) #x#y int main(void) { int a[N] , i , j , k , m; #ifdef N i=j; #else j=i; #endif i=10*INC(j); i=SUB(j,k); i=SQR(SQR(j)); i=CUBE(j); i=M1(j,k); puts(M2(i,j)); #undef SQR i=SQR(j); #define SQR i=SQR(j); return 0; }from here -> Answers to Selected Exercises in Chapter 14 of C Programming: A Modern Approach - Second Edition is wrong.Code:i=SUB(j,k);
It writes that i=SUB(j,k) would be i = (x,y) x-y(j, k);
My preprocessor and I have a different opinion.... i=SUB(j,k) would be i=j-k;
My gcc version is 4.4.5 ....
And a last one (really :P)
The value of expression of first #if is nonzero so the lines between would be compiled the others would be ignored #elif.... #endif...Code:#define C_LANG 'C' #define B_LANG 'B' int main(void) { #if C_LANG == 'C' && B_LANG == 'B' #undef C_LANG #define C_LANG "I know C language" #undef B_LANG #define B_LANG "I know B language" printf("%s,%s" , C_LANG , B_LANG); #elif C_LANG =='C' #undef C_LANG #define C_LANG "I know only C language" printf("%s" , C_LANG); #endif return 0; }
So why give an compilation error? They are not completely ignored ?
The error :
Code:sum.c:15: error: token ""I know C language"" is not valid in preprocessor expressions
Look again carefully at the code printed in the book. In my copy this line is:
Do you see the difference? Thus the expansion toCode:#define SUB (x,y) x-y
is correct.Code:i = (x,y) x-y(j, k);
The problem here is how the preprocessor works. First it seesCode:#define C_LANG 'C' #define B_LANG 'B' int main(void) { #if C_LANG == 'C' && B_LANG == 'B' #undef C_LANG #define C_LANG "I know C language" #undef B_LANG #define B_LANG "I know B language" printf("%s,%s" , C_LANG , B_LANG); #elif C_LANG =='C'
so C_LANG is 'C' (a character constant)Code:#define C_LANG 'C'
Then it sees
so C_LANG is now a string literalCode:#if C_LANG == 'C' && B_LANG == 'B' #undef C_LANG #define C_LANG "I know only C language"
And finally it sees
but you can't use a string literal here because #if and #elif must be followed by an integer constant expressions:Code:#elif C_LANG =='C'
Bye, AndreasOriginally Posted by C99 Standard (Draft)
Hmmmm .... I took the example from a book (Tony Zhang Teach your Self C in 24 hours is the label).
Ok, I've tested your example with gcc and clang:
It looks like they differ in their interpretation of the standard.Code:$ gcc -dumpversion 4.6.1 $ gcc foo.c foo.c: In function ‘main’: foo.c:15:7: error: token ""I know C language"" is not valid in preprocessor expressions $ clang -dumpversion 4.2.1 $ clang foo.c $ ./a.out I know C language,I know B language
I had some time for a research and I've found some discussion on the gcc bug tracker:
Bug 36320 – Required diagnosis of syntax error missed
Bug 38161 – [4.4 regression] #elif <non-const expression #defined in this #if> breaks
and on clang's bug tracker:
Bug 2291 – Undiagnosed syntax error (not checking dead #elif conditions)
and on comp.c.std (a newsgroup about the C Standard):
https://groups.google.com/d/topic/co...pko/discussion
https://groups.google.com/d/topic/co...bVk/discussion
And finally there is a defect report, so it seems a future revision of the standard will adopt clang's interpretation.
Bye, Andreas