1ce
asked on
Silly #define thing
#ifdef DEBUG_FILE
FILE *fp;
#define FPRINTF(x...) fprintf(fp,x); fflush(fp)
#else
#ifdef DEBUG_PRINT
#define FPRINTF(x...) fprintf(stderr,x); fflush(fp)
#else
#define FPRINTF(x...) ;
#endif //debug_print
#endif //debug_file
This #define works perfectly fine on gcc, however when i try to compile on msvc it gives
error C2010: '.' : unexpected in macro formal parameter list
???? =(
FILE *fp;
#define FPRINTF(x...) fprintf(fp,x); fflush(fp)
#else
#ifdef DEBUG_PRINT
#define FPRINTF(x...) fprintf(stderr,x); fflush(fp)
#else
#define FPRINTF(x...) ;
#endif //debug_print
#endif //debug_file
This #define works perfectly fine on gcc, however when i try to compile on msvc it gives
error C2010: '.' : unexpected in macro formal parameter list
???? =(
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Variable args in macros are part of the C99 std. MSVC (including .net) is based on C89 and does not support them. The others have suggested quite good workrounds.
Another, though less elegant, workaround is to define one macro for each realistic argument number:
#define TPRINT0(fmt) printf(fmt)
#define TPRINT1(fmt,arg1) printf(fmt,arg1)
[...]
#define TPRINT0(fmt) printf(fmt)
#define TPRINT1(fmt,arg1) printf(fmt,arg1)
[...]
Dont forget the:
#ifdef _DEBUG
... As above
#else // below is for release-mode
#define TPRINT(params)
#define TFPRINT(params)
#endif
#ifdef _DEBUG
... As above
#else // below is for release-mode
#define TPRINT(params)
#define TFPRINT(params)
#endif
Yes, the standards support of VC is crappy. Otherwise you could do in C99:
#define errout(fmt,...) fprintf(stderr,fmt,__VA_AR GS__)
#define errout(fmt,...) fprintf(stderr,fmt,__VA_AR
The TFPRINT(("Hello %s", "World")); solution has the severe disadvantage that you cannot pass different parameters (such as a file handle), and need a messy workaround. This is not necessarily portable, since there is no guarantee that stdout isn't defined const (and fsopen isn't ANSI).
Stefan,
>> ...cannot pass different parameters (such as a file handle),
I dont understand. By definition, you can do anything here that you can do with 'printf'. Oh! You want an 'fprintf' version! I'll leave this up to the student.
>> ... not necessarily portable
I fully agree! I called it '... pretty generic.'
The whole point of it is that the TFPRINT and TPRINT instructions COMPLETELY DISAPPEAR in the release version and they have printf(fmt,...)-like parameters.
I've used this or a variant in all my C development for about 10 years and it has saved me huge amounts of debug time. I'm not forcing you to use it. The crux of it is the use of (( )) that 'almost' allows you to do ... in #defines.
>> ...cannot pass different parameters (such as a file handle),
I dont understand. By definition, you can do anything here that you can do with 'printf'. Oh! You want an 'fprintf' version! I'll leave this up to the student.
>> ... not necessarily portable
I fully agree! I called it '... pretty generic.'
The whole point of it is that the TFPRINT and TPRINT instructions COMPLETELY DISAPPEAR in the release version and they have printf(fmt,...)-like parameters.
I've used this or a variant in all my C development for about 10 years and it has saved me huge amounts of debug time. I'm not forcing you to use it. The crux of it is the use of (( )) that 'almost' allows you to do ... in #defines.