Reputation: 33
I'm programming in Windows and MSVC. There are two ways to write a DEBUG_PRINT statement as I know of:
printf(__FUNCTION__": Error code: %x\n", ErrorCode);
printf("%s: Error code: %x\n", __FUNCTION__, ErrorCode);
Is it okay to concatenate predefined macro with strings like this? I don't know if predefined macro like __FUNCTION__
or __LINE__
is a legit string literal. And intuitively, seems like a dangerous way to treat strings like this in C.
And what's the difference between these two? As I used /FAcs compiler option to output the code snippet to assembly, I really can't see much of a difference.
Upvotes: 2
Views: 1827
Reputation: 33
Thanks for answering. Looks like the first way is a legit literal string concatenate, it just does it in build-time, and it's faster, just space consuming.
I think I'll stick in the first way. Thanks again.
Upvotes: 0
Reputation: 399803
The former will concatenate the function name in __FUNCTION__
with the format string at compile-time. The second will format it into the output at runtime.
This assumes it's a pre-defined macro (it's not standard). MSVC has __FUNCTION__
as a proper string literal, GCC does not.
__LINE__
is supported by GCC, and expands to a decimal integer, i.e. not a string.
For performance reasons, I would suggest always using the first way when possible, i.e. when the two strings are compile-time constant. There will be a price to pay, as usual: the string pool will be larger, since each use of the macro creates a unique format string. For desktop-class systems, this is probably neglible.
Upvotes: 1
Reputation: 14360
First of all __FUNCTION__
is not in the C standard, you should probably use __func__
instead (except that microsoft has decided to skip support for that in their C compiler).
Second __FUNCTION__
/__func__
"macro" is not really a macro (or at least not normally - microsoft's compiler seem to behave differently), it behaves more like a local variable and therefore it isn't a candidate for the string concatenation. You should use string formatting instead (since that will ensure that your code will become more portable).
The __LINE__
macro (is a macro), but it doesn't work well with string concatenation directly since it doesn't expand to a string - it expands to a number (which by the way can be useful in other cases). However you can use the preprocessor to stringify it (the XSTR
macro will first expand it's argument and then stringify the result while STR
will not expand the it's argument before stringifying it):
#define STR(x) # x
#define XSTR(x) STR(x)
printf("I'm on line #" XSTR(__LINE__));
The __FILE__
macro (which is also a macro) does expand to a string literal which plays well together with string concatenation directly.
The reason you don't see any difference is that the compiler knows what printf
does and can use that for optimization. It would figure out that it doesn't need to rely on printf
code to expand the %s
at runtime since it can do it at compile time.
Upvotes: 2
Reputation: 213711
The difference is that in the 1st case the string literal gets concatenated with the format string during the compiler translation phases, while in the second case, it gets read in during run-time. So the first method is much faster.
If you know that the macro is a pre-defined string literal, I don't see anything wrong with the code.
That being said, I have no idea what __FUNCTION__
is. There is a standard C macro __func__
but it is not a string literal and should be treated like a const char array.
__LINE__
is a standard C macro that gives the source file line as an integer.
Upvotes: 0