#include <stdio.h>
#define a (1,2,3)
#define b {1,2,3}
int main()
{
unsigned int c = a;
unsigned int d = b;
printf("%d\n",c);
printf("%d\n",d);
return 0;
}
Above C code will print output as 3
and 1
.
But how are #define a (1,2,3)
and #define b {1,2,3}
taking a=3 and b=1 without build warning, and also how ()
and {}
are giving different values?
The C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be the inclusion of header file, macro expansions etc. All preprocessing directives begin with a # symbol. For example,
#define preprocessor allows you to define a macro. A macro is a piece of code to which you can assign a name. Before compilaltion, the compiler replaces the name with the macro body wherever it has been introduced. Macros can also made to work like functions. This is known as function-like macros.
The C preprocessor directives allows transformation of code before compilation. All preprocessing directives starts with the # symbol. #define preprocessor allows you to define a macro. A macro is a piece of code to which you can assign a name. Before compilaltion, the compiler replaces the name with the macro body wherever it has been introduced.
Commands used in preprocessor are called preprocessor directives. All preprocessor directives starts with #. The source code of the program begins to executes, preprocessor replace #define (macro), #include (files), conditional compilation codes like #ifdef, #ifndef by their Respectative values & source codes in source file.
Remember, pre-processor just replaces macros. So in your case you code will be converted to this:
#include <stdio.h>
int main()
{
unsigned int c = (1,2,3);
unsigned int d = {1,2,3};
printf("%d\n",c);
printf("%d\n",d);
return 0;
}
In first case, you get result from ,
operator, so c
will be equal to 3
. But in 2nd case you get first member of initializer list for d
, so you will get 1
as result.
2nd lines creates error if you compile code as c++
. But it seems that you can compile this code in c
.
In addition to other answers,
unsigned int d = {1,2,3};
(after macro substitution)
is not valid in C. It violates 6.7.9 Initialization:
No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
With stricter compilation options (gcc -std=c17 -Wall -Wextra -pedantic test.c
), gcc produces:
warning: excess elements in scalar initializer
unsigned int d = {1,2,3};
^
However, note that
unsigned int d = {1};
is valid because initializing scalar with braces is allowed. Just the extra initializer values that's the problem with the former snippet.
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