I have been searching for an hour about this seemingly obvious question, and read several other posts including this one with the same title, but I am still struggling to find a convincing answer. Please forgive my ignorance in advance, and consider this code:
#define MY_MACRO 1
#define IMPLEMENT(x) (defined(x) && (x))
#if IMPLEMENT(MY_MACRO)
#define TESTVAL 1
#else
#define TESTVAL 0
#endif
#include <stdio.h>
int main()
{
printf("Value is %d\n", TESTVAL);
return 0;
}
Which doesn't compile and the error messages are:
error: operator "defined" requires an identifier
error: missing '(' in expression
One of the answers in the linked thread says the argument of IMPLEMENT is not known at compile-time, so we cannot use it with '#if defined'. But I don't think this is the case here. Can anyone explain why this doesn't compile?
Bonus question: is there any trick to safely replace the line #if defined(x) && x?
Can anyone explain why this doesn't compile?
IMPLEMENT(MY_MACRO) is expanding MY_MACRO to 1 and then replacing it for defined(1). defined(1) is invalid. 1 is not an identifier.
is there any trick to replace the line #if defined(x) && x?
Yes, just use #if x. If it's not defined, then it's zero. Just #if x, no need for a defined.
#if MY_MACRO
Related
I saw the following in a .h-file for the cc2640 mcu:
#define ADC_STATUS_SUCCESS (0)
From my C knowledge, the compiler is told to put the value of ADC_STATUS_SUCCESS everywhere it occurs, that is (0). But what is the difference in putting just 0?
what is the difference in putting just 0?
None, if you don't write crazy code. It is common to use parentheses for macros that contain expressions to avoid unexpected errors related to operator precedence and similar stuff when using them. In this case though, defining something as 0 or as (0) is the same if it's used in expressions.
What do I mean by "crazy code"? Well, the only difference between the two can be seen in something like the following:
void func(int x) { /* ... */ };
#define ADC_STATUS_SUCCESS 0
func ADC_STATUS_SUCCESS; // INVALID
#define ADC_STATUS_SUCCESS (0)
func ADC_STATUS_SUCCESS; // VALID (for the love of God NEVER do this)
I highly doubt this is the case though, nobody in their right mind would write such an abomination. That define is most likely out of habit.
I have code containing many lines such as:
static_assert(sizeof(my_stuct)==42, "check struct size");
and I want to compile on a compiler which has no static_assert implemented. So I want these lines to become no-op. I've tried:
#define static_assert(COND, MSG)
it works fine but I get a warning with clang compiler:
warning: extra ';' outside of a function [-Wextra-semi]
Is there a simple no-op C statement to be used outside functions which terminates with a semicolon and which can be used repeatedly?
I want to compile on a compiler which has no static_assert implemented. So I want these lines to become no-op.
Why not combining Lundin's answer (checking whether the current compiler has it implemented or not) with an implementation of static_assert (which is not hard to do)?
Copying the implementation from PDCLib (which is CC0 licensed):
/* with dodgy implementations, you could also #ifndef static_assert */
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
#define _PDCLIB_cc( x, y ) x ## y
#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
#define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
#endif
For a given expression e and message m, this declares an anonymous enumeration with one member, the name of which is _PDCLIB_assert_ concatenated with the current source file line (__LINE__) (so you can have multiple static_assert() per source file). This member is set to 1 divided by 1 if the expression e is true, or divided by 0 if the expression is false, which leads to output like this for a failed assert:
./path/to/source.c:57:94: warning: division by zero [-Wdiv-by-zero]
#define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
^
./path/to/header.h:571:1: note: in expansion of macro 'static_assert'
static_assert( false, "test" );
^
./path/to/source.c:57:62: error: enumerator value for '_PDCLIB_assert_571' is not an integer constant
...
It's not pretty, but it's perfectly C89-compliant, tested, and servicable.
Feel free to rename from _PDCLIB_* to anything you prefer.
My solution so far:
#define static_assert(COND, MSG) extern int __static_assert_dummy__
works fine but seems ugly to me!
Since this is a C11 feature, the answer is quite trivial: simply check if the compiler supports C11.
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112
static_assert(sizeof(my_stuct)==42, "check struct size");
#endif
The opposite, to make this a no-op in the absence of standard C, and thereby remove the need for the above compiler switches all over the place, is this:
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
#define static_assert(cond, str) struct dummy_t
#endif
Though remember that static_assert requires #include <assert.h>, unlike the C11 keyword _Static_assert.
Tested only very quickly, but how about:
#define static_assert(COND, MSG) extern int _no_static_assertion
or something? Repeating an extern should be fine.
This question already has answers here:
C : #define usage [duplicate]
(3 answers)
Closed 7 years ago.
#include <stdio.h>
#define SQR(x) x*x
int main()
{
printf("%d",225/SQR(15));
return 0;
}
The output to this code is 225. I'm unable to understand as what really is happening here.
If I use #define SQR(x) (x*x) Then it works fine which i get as we are supposed to use parentheses if we have an expression with some operator.
But in the previous case I'm not clear as to what is really happening. Why is the answer 225?
#define macros aren't functions - they are just macros, text replacement. If you take the expression 225/SQR(15) and replace SQR with 15*15, you'll get 225/15*15, and since / and * have the save precedence and are left associative - 255/15*15 = 255.
Macros do substitution only(done before compilation of the code).
Therefore the following line
printf("%d",225/SQR(15));
after substitution will become:
printf("%d",225/15*15);
now this expression evaluates to 225 (basic maths : divide first -> 15*15, then multiply -> 225)
using brackets solves your problem(then it becomes 225/(15*15)).
:)
Notice the steps
1) 225/SQR(15)
2) 225/15*15
Division executed first due to precedence
3) 15*15
4) 225
See #define as a text replacement tool in a text editor; it works the same way (well, almost).
Here are two rules you might want to follow in order to avoid this kind of errors:
When working with macros, always use parentheses for each "variable" given to the macro and for the whole result.
Example:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
When you have an unexpected behavior, use the command line tool cpp (c preprocessor) to see how the macro is actually interpreted.
Example:
$ cpp main.c
When I run the following code,
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("%d",4*X+2);
return 0;
}
I am getting the following output:
Error: Undefined symbol 'X'
Can someone please explain the output?
It is because the macro expects and argument since its defined with parentheses.
You would need to define it as
#define X 4+Y and #define Y X+3. Then you would run into another trouble because of cyclic definition in macros.
To be even more correct, as Drew suggested; when the example would be compilable when defining macros one usually puts the parentheses around expression to ensure expected operator precedence.
So your best shot would be:
#define X (4+Y)
#define Y (X+3)
Very close to your initial example, just a space character between name of a macro and its definition. However, it is still impossible to properly expand the macro due to the cyclic reference.
How to check what happened:
You can use gcc -E, which outputs a pre-processed file. It generates lots of output so I used tail. I also used 2>err to redirect error stream to a file, so the output is clear.
luk32:~/projects/tests$ gcc -E ./cyclic_macro_with_no_spaces.c 2> err | tail -n 6
int main()
{
printf("%d",4*X+2);
return 0;
}
luk32:~/projects/tests$ gcc -E ./cyclic_macro.c 2> err | tail -n 6
int main()
{
printf("%d",4*(4+(X+3))+2);
return 0;
}
In 1st example the X did not expand at all. While in the latter both macros got expanded, although only one. Giving the same output that Geoffrey presented in his answer.
Whether no space is a typo or not there is an undefined symbol 'X'. For different reason that are possible to trace by analyzing err files.
If the macros are left as invalid function-like macros, they are not getting expanded at all because you did not call it with parentheses. So X is never replaced with anything by the pre-processor, and is the reason for the Undefined symbol 'X' in your sample code.
If you wanted this to be expanded you would have to call it with parentheses like this:
printf("%d",4*X()+2);
This though would just error out when pre-processed as 4+Y and X+3 are not valid macro parameter names.
If your answer is corrected somewhat so that those defines are proper defines, and not function-like macros, ie:
#define X (4+Y)
#define Y (X+3)
You have a circular reference between the defines...
X -> Y -> X... etc.
Since it will only expand the macro once, it is getting expanded to
printf("%d",4*(4+(X+3))+2);
This explains why X is the undefined symbol in this use case.
You miss spaces
#define X (4+Y)
#define Y (X+3)
i am writing in c, using Visual c++.
The compiler gives me the errors with the code below:
#define SIZE 3;
int myMatrix[SIZE][SIZE];
void funcMatrix(int M[SIZE][SIZE]);
The errors i get:
error C2143: syntax error : missing ']' before ';'
error C2059: syntax error : ']'
Ive tried declaring the constant differently, inside main and outside. It still doesn't work.
Would really appreciate it if someone can help me out...
You should use #define SIZE 3.
Preprocessor works as a raw string substitution, so with #define SIZE 3; your SIZE is replaced with 3; and you get:
int myMatrix[3;][3;];
void funcMatrix(int M[3;][3;]);
as a final result, hence the errors. This is a common error, then you get used to place ; at the end of C expression. However the preprocessor #define-s are not C code actually, but a simple (or not so simple) string processing operation which occurs before compilation.
In your code SIZE will be replaced by the define in this case 3; so you'll have
int myMatrix[3;][3;];
void funcMatrix(int M[3;][3;]);
Which causes a syntax error, so use #define SIZE 3 (without the ;) instead of #define SIZE 3;.
A #define NAME literally inserts whatever value comes after NAME.
Your macro expands to
int myMatrix[3;][3;];
Remove the ; in the macro definition.
you change :
#define SIZE 3;
to
#define SIZE 3
You need to remove the ; after the #define SIZE 3.
#defines don't require a semicolon
#define SIZE 3 not #define SIZE 3;
You can see what the compiler sees.
It can be a mess if you don't comment out included header files,
and I don't know how to do it in Visual C++,
but with GCC you run
gcc -E xx.c > xx.e
and you see what your code expands to after the #define's are processed.
There must be some way to do that with Visual C++ too.
Then you can still compile the .e file as c code.