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()?
constant. noun. Definition of constant (Entry 2 of 2) : something invariable or unchanging: such as. a : a number that has a fixed value in a given situation or universally or that is characteristic of some substance or instrument.
#define in C is a directive which is used to #define alias.
A constant is a name given to the variable whose values can't be altered or changed. A constant is very similar to variables in the C programming language, but it can hold only a single variable during the execution of a program.
Overview. Variables having fixed values that don't change and cannot be changed throughout the execution of the program once initialized are called Constants. There are mainly two types of constants: primary and secondary.
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 printf
is to do this:
#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300
int main()
{
printf("%d %f", (int)LOWER, (float)UPPER);
return 0;
}
In both cases, these are preprocessor macros that are substituted before compilation. Note that if UPPER cannot be promoted to a float
you will receive a compiler error, which is a good thing. if it can be, it will be, and the printf()
will find the bytes it needs to print what it wants. The same is true for int
and LOWER respectively. The above printf will degenerate to this after preprocessing:
printf("%d %f", (int)0, (float)300);
Now imagine your macros were instead declared as such:
#define LOWER 100.0
#define UPPER 300.0
The original printf()
will present as thus after preprocessing:
printf("%d %f", 100.0, 300.0);
which may seem right, but is that 100.0 float really going to be properly excised by the %d
format string handler in printf()
? Make sure. Doing what we did before:
printf("%d %f", (int)LOWER, (float)UPPER);
now preprocesses to:
printf("%d %f", (int)100.0, (float)300.0);
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:
printf("%ld\n", UPPER);
This may "work", but if it does it is only because a long int
and a int
are the same size on your platform. Move this code to a platform where long int
and int
are 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.
In this case, the type is the type of the literal constants. Both 0
and 300
are integer constants that fit in an int
, so their type is int
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With