Why does the code snippet 1 works but NOT code snippet 2
Code Snippet 1:
#define mkstr(x) #x
int main(void)
{
printf(mkstr(abc));
return (0);
}
Code Snippet 2:
int main(void)
{
printf(#abc);
return(0);
}
The first snippet works because it has a function-like macro defined in which you put anything, the value is correctly assigned as a constant.
OTOH, the second one has a syntactic error because the compiler doesn't expects that parameter passed in printf(). Thus, the # is meaningless there.
Commands starting with the # symbol are called Macros in C and C++. Macros are blocks of code that are named and referenced with that name.
There are 2 popular types of macros - the Object-like and the function-like. The one you're using is the function-like macro.
The Preprocessor is responsible for replacing macro calls with the actual object/function calls.
The statement in Snippet 1
#define mkstr(x) #x
The above macro uses a special feature called the stringizing. The # before the x specifies that the input parameter should be treated as is, ie. converted to a string constant, thereby returning a string equivalent of what is passed.
On the contrary, when you call the below code in Snippet 2
printf(#abc);
doesn't mean anything. It's a compiler error as #s are not allowed in the middle or end of a statement (please not that # is allowed to be part of string such as "#1", or when used as a character literal as '#'). And thus any statement that starts with # becomes a macro.
Caution: Use of macros is discouraged. You can refer this answer on StackOverflow on why not to use them.
Refer the below resources to learn more about macros
Macro (The C Preprocessor) - GNU GCC
C Preprocessors and Macros - Programiz
Related
From what I understand about macros in C, they are predefined constants that will be used throughout the program with their constant value, so we go ahead and define them to avoid further complications and make the code more readable, so people reading it will understand what is supposed to stay constant and what isn't.
I have read here and there (C programming A Modern Approach, K.N King) that we can define these two functions as macro.
Since I'm somewhat new to C, I can't wrap my head around how can these two be defined as macro?
There are two types of macros: simple substitution macros and function-like macros.
Substitution macros replace one instance of a symbol with another. For example:
#define LEN 10
char str[LEN];
After preprocessing, this becomes:
char str[10];
A function-like macro can take parameters that can be plugged in to whatever gets substituted:
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int x = MAX(2,3);
After preprocessing:
int x = ((2) > (3) ? (2) : (3));
In the case of getchar and putchar, they can be defined as follows:
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)
There are basically three types of preprocessor macros:
Simple defined without any value. For example
#define THIS_IS_A_MACRO
This kind of macros are used for conditional compilation.
Symbolic constants. For example
#define SOME_SYMBOLIC_CONSTANT 123
These kind of macros are what you're thinking of.
Function-like macros. Foe example
#define SOME_MACRO(a_macro_argument) printf("Macro invoked with argument %d\n", a_macro_argument)
This kind of macro is used very much like functions, but are replaced by the preprocessor in the source code before the compiler parser sees the code, with the macro arguments replaced with their actual values.
Lets take the function-like macro and how it will be expanded by the preprocessor:
SOME_MACRO(123);
The above will be replaced like
printf("Macro invoked with argument %d\n", 123);
Fully depends on implementation. They can be function also.
Standards don't demand anything explicit about the type of implementation. But you can check here it points Any function declared in a header may be additionally implemented.... as pointed by Eugene.Sh
To say it more clearly, there may be a function in the library or it can be a macro also (for getchar). Classically, the macro for getchar() would be #define getchar() getc(stdin), and getc() might also be a macro.
Standard says that The getc function is equivalent to fgetc, except that if it is implemented as a macro, it may evaluate stream more than once, so the argument should never be an expression with side effects.
Now it boilds down to fgetc in which case we know that it is guaranteed to be a function. Thread safety makes it more likely to be a function.
Thus, in C++, never define getchar and putchar as member functions of a class. In case, they are defined as macros in stdio.h file, the compiler would throw all sorts of strange errors.
#include <stdio.h>
class My_IO_Device
{
int putchar (int c); // seemingly innocent
};
I do not know whether <cstdio> guarantees them to be implemented as functions.
Here is what confuses me:
To define a function-like macro, you use the same '#define' directive, but you put a pair of parentheses immediately after the macro name.
I believe this is to make the code stand out for people other than the author of the program. Like other rules of CAPS for macro names. But the following is where I get confused:
A function-like macro is only expanded if its name appears with a pair of parentheses after it. If you write just the name, it is left alone.
I disagreed instantly after reading it. And gcc -E verified that in the following code
#define FUNC display()
void display()
{
printf("Display\n");
}
int main()
{
FUNC;
return 0;
}
The pre-processed output shows the content of the main() function as expected:
int main()
{
display();
return 0;
}
So what am I missing here? The pre-processor is for tokenizing the source, the macro expansion is a token and the above code was processed that way, the pre-processor isn't supposed to check anything or verify anything, it just dumps tokens. In that case what is the gcc manual trying to convey.
I am learning C programming, so I might be misunderstanding it a great deal as it frequently happens, I searched for a proper explanation and finally resorted to asking here. Please help me with this.
When you define:
#define FUNC display()
FUNC is not a function-like macro; it is an object-like macro that expands to a function call.
A function-like macro looks like:
#define FUNC() display()
Now you must write FUNC() to invoke it. Or, more frequently, it will have arguments:
#define MIN(x, y) ((x) > (y) ? (x) : (y))
and that can be invoked with:
int min = MIN(sin(p), cos(q));
with cautions about the number of times the arguments are expanded.
See also getc() as macro and C standard library function definition. It includes the standard's explanation of why it is important that the simple name of a function-like macro without a following open parenthesis is not expanded, which is what the quote from the GCC manual is telling you.
When a function-like macro is defined, the open parenthesis must 'touch' the macro name:
#define function_like(a) …
#define object_like (…)
Because there's a space after object_like, the open parenthesis is part of the replacement text, not the start of an argument list. When the function-like macro is invoked, there may be spaces between the macro name and the argument list:
function_like (x) // Valid invocation of function_like macro.
However, if you wrote:
int (function_like)(double a) { return asin(a) + 2 * atanh(a); }
this is not an invocation of the function-like macro because the token after function_like is not an open parenthesis.
There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
You may define any valid identifier as a macro, even if it is a C keyword. The preprocessor does not know anything about keywords. This can be useful if you wish to hide a keyword such as const from an older compiler that does not understand it. However, the preprocessor operator can never be defined as a macro, and C++'s named operators cannot be macros when you are compiling C++.
I have encountered the following debug macro in an embedded device codebase:
extern void DebugPrint(uint8_t *s);
#define DEBUG_MSG(x) do { PRINT_CURRENT_TIME; \
DebugPrint x ; } while(0)
Since there are no parentheses around x in the macro body (at the DebugPrint x part), all calls to this macro (all over the codebase) add another set of parentheses around strings:
DEBUG_MSG(("some debug text"));
Is there any reason to do this? Does it simplify optimizing away these calls in release builds, or something like that? Or is it just plain nonsense?
I thought perhaps there would be additional overloads of DebugPrint with more arguments, but there are none.
Here's a theory:
The preprocessor parses the arguments of a macro expansion in a way that mimics the compiler's expression parsing. In particular it parses terms in parentheses as a single argument.
So the DEBUG_MSG author's intention might have been to enforce the use of parentheses.
This might make sense when the DebugPrint print function would actually be a printf style variadic function. You could call the function with a single string literal or with a variable number of arguments:
DEBUG_MSG(("reached this point in code"));
DEBUG_MSG(("value of x = %i", x));
But this is pure speculation. Can't you just ask the author?
I believe that no. Macros are replaced by the compiler, so they have nothing to do with execution speeds. This:
#define MACRO(x) do_something(x)
MACRO("test");
Is no different than this
#define MACRO(x) do_something x
MACRO(("test"));
Since the compiler will replace them both with the same output:
do_something("test");
which will then compile to produce the same object code.
After reading through some of K&R's The C Programming Language I came across the #define symbolic constants. I decided to define...
#define INTEGER_EXAMPLE 2
#define CHAR_EXAMPLE 2
...so my question is how does C know if I'm defining an int or a char type?
#define-d names have no types. They just define textual replacements.
What the compiler is seeing is the preprocessed form. If using GCC, try gcc -C -E somesource.c and have a look at the (preprocessed) output.
In the 1980s the preprocessor was a separate program.
Read about the cpp preprocessor, and preprocessor and C preprocessor wikipages.
You could even define ill-defined names like
#define BAD #*?$ some crap $?
And even more scary you can define things which are syntactically incomplete like
#define BADTASTE 2 +
and later code BADTASTE 3
Actually, you want to use parenthesis when defining macros. If you have
#define BADPROD(x,y) x*y
then BADPROD(2+3,4+5) is expanded to 2+3*4+5 which the compiler understands like 2+ (3*4) +5; you really want
#define BETTERPROD(x,y) ((x)*(y))
So that BETTERPROD(2+3,4+5) is expanded to ((2+3)*(4+5))
Avoid side-effects in macro arguments, e.g. BETTERPROD(j++,j--)
In general, use macros with care and have them stay simple.
Regarding these defines, it doesn't, the expanded macros doesn't have a type. The pre-processor which processes the #define is just replacing text within the source code
When you use these defines somewhere, e.g.
int i = INTEGER_EXAMPLE;
This will expand to
int i = 2;
Here the literal 2 (which in this context is an int) is assigned to an int.
You could also do:
char c = INTEGER_EXAMPLE;
Here too, the literal 2 is an int, and it is assigned to a char. 2 is within the limits of a char though, so all is ok.
You could even do:
int INTEGER_EXAMPLE = 2;
This would expand to
int 2 = 2;
Which isn't valid C.
#define STRING VALUE
is just an instruction for the pre-processor to replace the STRING with VALUE
afterwards the compiler will take control and will check the types
It doesn't, this is the preprocessor. The type of the constant is dependent on the context in which it is used. For instance:
#define INT_EXAMPLE 257
char foo = INT_EXAMPLE;
will attempt to assign 257 in a char context which should generate a warning unless char has more than 8 bits on your computer.
#Defines are nothing but literal replacements of values. You might want to use
static const
As it respects scope and is type-safe. Try this:
#define main no_main
int main() // gets replaced as no_main by preprocessor
{
return 0;
}
Should give you linking errors. Or you could try and fool your teacher by this
#define I_Have_No_Main_Function main //--> Put this in header file 1.h
#include"1.h"
int I_Have_No_Main_Function()
{
return 0;
}
It doesn't. The #define statements are processed before the compiler starts its work. Basically the pre-processor does a search and replace for what you wrote and replaces it, for instance, all instances of INTEGER_EXAMPLE are replaced with the string 2.
It is up to the compiler to decide the type of that 2 based on where it's used:
int x = INTEGER_EXAMPLE; // 2 is an integer
char y = INTEGER_EXAMPLE; // 2 is a char
Preprocessor cannot know the type of the macro definition. Preprocessor will just replace all occurrence of 'CHAR_EXAMPLE' with '2'. I would use cast:
#define CHAR_EXAMPLE ((char)2)
At least some C preprocessors let you stringize the value of a macro, rather than its name, by passing it through one function-like macro to another that stringizes it:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
Example use cases here.
This does work, at least in GCC and Clang (both with -std=c99), but I'm not sure how it works in C-standard terms.
Is this behavior guaranteed by C99?
If so, how does C99 guarantee it?
If not, at what point does the behavior go from C-defined to GCC-defined?
Yes, it's guaranteed.
It works because arguments to macros are themselves macro-expanded, except where the macro argument name appears in the macro body with the stringifier # or the token-paster ##.
6.10.3.1/1:
... After the arguments for the
invocation of a function-like macro
have been identified, argument
substitution takes place. A parameter
in the replacement list, unless
preceded by a # or ## preprocessing
token or followed by a ##
preprocessing token (see below), is
replaced by the corresponding argument
after all macros contained therein
have been expanded...
So, if you do STR1(THE_ANSWER) then you get "THE_ANSWER", because the argument of STR1 is not macro-expanded. However, the argument of STR2 is macro-expanded when it's substituted into the definition of STR2, which therefore gives STR1 an argument of 42, with the result of "42".
As Steve notes, this is guarenteed, and it has been guarenteed since the C89 standard -- that was the standard the codified the # and ## operators in macros and mandates recursively expanding macros in args before substituting them into the body if and only if the body does not apply a # or ## to the argument. C99 is unchanged from C89 in this respect.