I was trying this code.
#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300
int main()
{
printf("%d %f",LOWER,UPPER);
return 0;
}
I read some of the answers and it says that defined constants don’t have a type and are not allocated any memory.
Then why is it giving errors if i specify different type specifiers in printf()?
In your example, both are pushed into the variadic parameter list of printf as int values. This can cause problems with the format flags in the format string of
printf()do not match the underlying type. Refer to this post for reasons why undefined behavior can ensue.As hideous as it seems, one way to know you can get what you’re looking for in this
printfis to do this:In both cases, these are preprocessor macros that are substituted before compilation. Note that if UPPER cannot be promoted to a
floatyou will receive a compiler error, which is a good thing. if it can be, it will be, and theprintf()will find the bytes it needs to print what it wants. The same is true forintand LOWER respectively. The above printf will degenerate to this after preprocessing:Now imagine your macros were instead declared as such:
The original
printf()will present as thus after preprocessing:which may seem right, but is that 100.0 float really going to be properly excised by the
%dformat string handler inprintf()? Make sure. Doing what we did before:now preprocesses to:
You may get a compiler warning on the float-to-int cast, you may not. Unless you want to roll the dice that what you’re passing is sized to what is byte-size-expected by things like
printf()you need to be damn-sure everything matches. This can get especially frustrating when the format specifier expects one thing, something different is passed in, and yet it appears to all work fine, but only on some platforms mysteriously:This may “work”, but if it does it is only because a
long intand aintare the same size on your platform. Move this code to a platform wherelong intandintare different bit-widths and its UB all the way.Bottom line: If you’re passing preprocessor macros into variadic parameter lists for things like
printf()that have size expectations for the data being pushed (as specified by the format string for example) you better make sure what you’re pushing is what is expected.