Using #define in C with no value - c

If a #define is used with no value, like
#define COMMAND_SPI()
does it take value 0 by default?

No, it evaluates to nothing. Literally the symbol gets replaced with nothing.
However, once you have #define FOO, the preprocessor conditional #ifdef FOO will now be true.
Note also that in gcc and possibly other compilers, if you define a macro with -DFOO on the command line, that evaluates to 1 by default.
Since the OP updated his question to reference function-like macros, let's consider a small example.
#define FOO
#define BAR()
FOO
BAR
BAR()
This is not a valid C program, but the preprocessor does not care.
If I compile this with gcc -E Input.c, I get a blank, followed by BAR followed by another blank. This is because the first and third expressions evaluate to nothingness, and the middle expression is not expanded because there are no () after it.

Related

Function-like C macro without parentheses

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.

What value to expect from a macro that has been set to the result of defined()?

In the very simple C program below, what is the expected compiler error? gcc is giving me 1 whereas MSVC 2013 is giving me 2.
#define foo
#define bar (defined(foo))
#if bar
#error 1
#else
#error 2
#endif
My questions are hopefully equally simple:
What does the C spec say about the value of defined()? I can't seem
to find anything that talks about setting its value to another
macro.
The actual code is not something I have control over and "#if bar" is used all over the place. What is the simplest way to change the #define so that #if bar will work as "expected" in MSVC? The only thing I can think of is to expand it out:
.
#ifdef foo
#define bar 1
#else
#define bar 2
#endif
The C spec says:
§6.10.1/1 The expression ... may contain unary operator expressions of the form defined identifier or defined(identifier) which evaluate to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.
§6.10.1/4 macro invocations in the list of preprocessing tokens that will become
the controlling constant expression are replaced (except for those macro names modified
by the defined unary operator), just as in normal text. If the token defined is
generated as a result of this replacement process or use of the defined unary operator
does not match one of the two specified forms prior to macro replacement, the behavior is
undefined. After all replacements due to macro expansion and the defined unary
operator have been performed, all remaining identifiers (including those lexically
identical to keywords) are replaced with the pp-number 0, and then each preprocessing
token is converted into a token.
(emphasis mine)
However, how macro replacement is very complex, and I think MSVC is defining foo as defined(bar) which is undefined behavior, wheras GCC is defining foo as 1 correctly. Since MSVC is then in undefined behavior, it does strange things.
As you say, the easiest fix is
#ifdef foo
#define bar 1
#else
#define bar 2
#endif
I believe the compiler will see everything after the name/macro being defined as part of the definition of the name/macro, that is, as program text, not as macro text.
int defined(char s); // prototype of a function named "defined"
#define foo
#define bar defined(foo)
"bar" anywhere in the program text will now be replaced with a call to defined() with no argument (as "foo" is defined as empty).

Embedding preprocessor directive into function name

I want to embed a preprocessor directive into a function name. Basically I want to make a macro that takes a preprocessor define as argument and concatenates it's defined VALUE to get a function name.
Basically this:
#define PREFIX foo
#define CALL(P, x) _##P_bar(x)
...then
CALL(PREFIX, x) should become _foo_bar(x)
Unfortunately this results in _P_bar instead of _foo_bar.
Is it possible to make it work as above?
The C standard defines special behavior for macro parameters immediately preceded and followed by ## operator. In such case they are not fully expanded. This is why your code did not behave as you expected. To further expand a parameter, you have to use it in a way that it is not immediately preceded or followed by ## operator. Try the following:
#define PREFIX foo
#define CALL2(P,x) _##P##_bar(x)
#define CALL(P, x) CALL2(P,x)
CALL(PREFIX, x)

Symbolic constants in C (#define statement)

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)

Double slash comment substituition within a macro

I am developing a PIC MCU program on an ansi-compliant compiler (Microchip XC8).
There are two operation modes, determined via macros during compilation time.
So that I don't want to duplicate one function-like macro due to one line of code, I would like to know if there is any way to write a macro such as
#define FOO //
so that when FOO is substituted it will actually cancel the rest of the line.
Writing a function instead of a macro is out of the question because the delay generated by function calls would disrupt the tight timings of my program (around some microseconds).
You can't make a macro expand to comment out the line, no. // in a macro definition is a comment following the definition, it's not expanded, and IIRC there's a rule saying that you cannot construct a // using token-pasting. Even if you can, expanding it doesn't mean that the macro starts a comment. Basically, you don't get to change the comment syntax using macros.
You could do:
#if DO_NOTHING_MODE
#define FOO(ARG1)
#else
#define FOO(ARG1) ARG1
#endif
and use it like:
#define FUNCTION_LIKE_MACRO(ARG1, ARG2) \
required line; \
FOO(optional line;) \
Although a more common idiom is to design the macro to accept an expression as its argument, rather than a whole line:
#if DO_NOTHING_MODE
#define FOO(ARG1) ((void)0)
#else
#define FOO(ARG1) (ARG1)
#endif
and use it like FOO(optional line);
Either way, if the macro argument has commas in it, then the caller needs to enclose them in parentheses FOO((1,2)), although in C99 you can avoid that by making FOO a variadic macro:
#define FOO(...) (__VA_ARGS__)
You can use the #ifndef directive to achieve the same effect:
#ifndef FOO
your_line_of_code
#endif
EDIT: #SteveJessop made me see I didn't pay attention to this sentence of the OP "I don't want to duplicate one function-like macro due to one line of code". Here is what could be done in that case, if duplicating the function-like macro is not wanted:
// When FOO is defined, BLA in FUNC macro is a no-operation (null statement)
#ifndef FOO
#define BLA() a++
#else
#define BLA()
#endif
#define FUNC() \
BLA(); \
b++;
Comments are removed from the source before macro replacement occurs, so there's no way to define a macro exactly like that. However, it is certainly possible to pass an additional parameter into the macro to specify which code it should generate, or conditionally define the macro depending on the mode for which you are compiling.
#define FOO(...) __VA_ARGS__
And then use FOO(your code here) instead of FOO your code here in the macro.
If your platform doesn't have C99, you can instead use
#define FOO(x) x
and just make sure the argument doesn't contain a , not enclosed in ().

Resources