I made a mechanism for compiling only selected tests from a sequence of tests by defining the macros:
#define SELECTION(x) ((!defined (RUN_SELECTED_TESTS_ONLY)) || (defined (x)))
#define RUN_SELECTED_TESTS_ONLY
#define TEST_1 //Lets say I want only test1 to be compiled
#if SELECTION(TEST_1) //The line I'm getting the error on.
//code of test 1
#endif
#if SELECTION(TEST_2)
//code of test 2
#endif
While compilation I'm getting the error :
error C2003: expected 'defined id'
I'm getting the error only when TEST_1 or TEST_2 (or both) are defined.
An alternative definition for SELECTION:
#ifdef RUN_SELECTED_TESTS_ONLY
#define SELECTION defined
#else
#define SELECTION(x) 1
#endif
Notes:
Must be defined after RUN_SELECTED_TESTS_ONLY is.
Only works in GNU cpp and other preprocessors similarly permissive about operator defined being the result of a macro expansion.
Example:
#define RUN_SELECTED_TESTS_ONLY
#ifdef RUN_SELECTED_TESTS_ONLY
#define SELECTION defined
#else
#define SELECTION(x) 1
#endif
#define TEST_1
//#define TEST_2
#include <stdio.h>
int main()
{
#if SELECTION(TEST_1)
printf("Test 1\n");
#endif
#if SELECTION(TEST_2)
printf("Test 2\n");
#endif
return 0;
}
Output:
Test 1
What you have invokes undefined behaviour. C standard says that the defined preprocessor operator may not appear as a result of replacement.
C11 draft, 6.10.1 Conditional inclusion
4 Prior to evaluation, 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.
If you can't perform same check at run-time, you could do:
#define RUN_SELECTED_TESTS_ONLY
#define TEST_1
#if ((!defined (RUN_SELECTED_TESTS_ONLY)) || (defined (TEST_1)))
//code of test 1
#endif
Basically performing the "selection" yourself.
The error you get means: An identifier must follow the preprocessor keyword. (from MSDN).
It doesn't work because you cannot you defined() 2 times in your macro SELECTION(x).
What you can do instead is something like:
#define SELECTION(x) (!RUN_SELECTED_TESTS_ONLY || x)
#define RUN_SELECTED_TESTS_ONLY 1
#define TEST_1 1
#define TEST_2 0
#if SELECTION(TEST_1)
//some code
#endif
int main() {
printf("%d\n", SELECTION(TEST_1));
printf("%d\n", SELECTION(TEST_2));
return 0;
}
Related
Consider the following - I want to check with #if #endif whether a
token is defined somewhere in the code.
I am using a CONCAT(input) macro that should glue the constant and changing parts of the token that I want to check.
Unfortunately, the approach presented below causes a compilation error:
error: missing binary operator before token "("
I have found the expressions that can be put inside a #if #endif block:
https://gcc.gnu.org/onlinedocs/cpp/If.html#If
And apparently it states that:
Macros. All macros in the expression are expanded before actual computation of the expression’s value begins.
It turns out that (CONCAT(test)) should be resolved, but it is not.
Is there any workaround allowing to resolve concatenated token names correctly in a conditional compilation block?
#include <stdio.h>
#define CONCAT(input) string##input
#define stringtest 1
int main(void)
{
#if defined(CONCAT(test)) && (CONCAT(test)==1)
printf("OK");
#else
printf("NOT");
#endif
return 0;
}
If you use just: #if CONCAT(test) == 1 it will work and is enought.
The statement #if defined(CONCAT(test)) does not work because CONCAT(test) will be evaluated to stringtest which will be evaluated to 1, and you can't use defined on a numerical constant.
A different situation came to my mind - what if I want to check whether the token is eg. != 1 Then if it is not defined anywhere, the condition will evaluate to true. So there would be no difference between token not defined and token being different than 1.
You could handle == 0 equal to not defined. So you could use: #if CONCAT(test) != 0 && CONCAT(test) != 1 where CONCAT(test) != 0 means defined(CONCAT(test)). That is the only alternative, because you can't get macro expansion work in a #ifdef or #if defined() statement, see this question which is very similar to yours.
The gcc documentation says:
Conditionals written like this:
#if defined BUFSIZE && BUFSIZE >= 1024
can generally be simplified to just #if BUFSIZE >= 1024, since if BUFSIZE is not defined, it will be interpreted as having the value zero.
Also it can be helpful if you check macro expansion by using gcc -E yourSource.cpp.
gcc --help:
-E Preprocess only; do not compile, assemble or link
You can't do that. Only literals can be used.
You should check for macro directly:
#include <stdio.h>
#define CONCAT(input) string##input
#define stringtest 1
int main(void) {
#if stringtest == 1
printf("OK");
#else
printf("NOT");
#endif
return 0;
}
Since you don't need defined check, you can use like this:
#define CONCAT(input) string##input
#define stringtest 1
int main(void) {
#if CONCAT(test) == 1
printf("OK");
#else
printf("NOT");
#endif
return 0;
}
Suppose I have this code:
#define NAME MY_APP
#define ENABLE NAME ## _ENABLE
I want to check if the macro that ENABLE expands to is defined, i.e., if MY_APP_ENABLE is defined. Is this possible using C macros?
You can use the construct defined to check if a macro is defined, but it's only possible to use this in preprocessor expressions. It's possible to write a macro that expands to this construct. For example:
#define MY_APP_ENABLED
#define IS_DEFINED(x) defined(x ## _ENABLED)
#if IS_DEFINED(MY_APP)
#error "YES"
#else
#error "NO"
#endif
The above will issue YES when compiled. If MY_APP_ENABLED isn't defined, NO will be issued.
Update: The following version will work when NAME is defined to MY_APP. The extra level of indirections allows NAME to be expanded to MY_APP before it's concatenated with _ENABLED:
#define MY_APP_ENABLED
#define IS_DEFINED0(x) defined(x ## _ENABLED)
#define IS_DEFINED(x) IS_DEFINED0(x)
#define NAME MY_APP
#if IS_DEFINED(NAME)
#error "YES"
#else
#error "NO"
#endif
No. In particular, the suggested
#ifdef NAME ## _ENABLE
will not work, according to 6.10.3.4 Rescanning and further replacement, which says
The resulting completely macro-replaced preprocessing token sequence is not reprocessed as a preprocessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in 6.10.9 below.
I have concrete_impl.h (as is):
#ifdef TUPLE_ITERATOR_WITH_INDEX
#define TUPLE_ITERATOR TUPLE_ITERATOR_NO_INDEX
#define iterate_tuple_fname iterate_tuple_id
#else
#define TUPLE_ITERATOR TUPLE_ITERATOR_INDEX
#define iterate_tuple_fname iterate_tuple
#endif
#undef iterate_tuple_fname_back
#define iterate_tuple_fname_back iterate_tuple_fname##_back
static void iterate_tuple_fname() // ok
{
}
static void iterate_tuple_fname_back() // redefinition error
{
}
And concrete.h (as is):
#ifndef CONCRETE_H
#define CONCRETE_H
#define TUPLE_ITERATOR_WITH_INDEX
#include "concrete_impl.h"
#undef TUPLE_ITERATOR_WITH_INDEX
#include "concrete_impl.h"
#endif // CONCRETE_H
What I want to get - is 4 functions:
iterate_tuple
iterate_tuple_id
iterate_tuple_back
iterate_tuple_id_back
But on "_back" functions I have redefinition error. Why?
iterate_tuple_fname##_back is nothing else than iterate_tuple_fname_back. To have iterate_tuple_fname replaced by its macro replacement list, you'll need a helper macro:
#define CONCAT(a, b) a ## b
#define iterate_tuple_fname_back CONCAT(iterate_tuple_fname, _back)
UPDATE: Sorry, have forgotten all about C after several years of C# programming.
It actually needs double run through helper macros:
#define CONCAT1(a, b) a ## b
#define CONCAT(a, b) CONCAT1(a, b)
#define iterate_tuple_fname_back CONCAT(iterate_tuple_fname, _back)
Apparently you misunderstand how the ## operator works.
If the preprocessing token adjacent to the ## operator is a parameter of the current macro, then this parameter is recursively analyzed for further replacement first, and the result of that replacement substituted into the result.
If the preprocessing token adjacent to the ## operator is not a parameter of the current macro, then recursive analysis and replacement of that token does not take place. The token is simply concatenated with the other token.
Later, once all parameters are substituted and all concatenations are joined, the entire result is rescanned again for further replacements. But then it is already be too late for your example.
In your case you defined this macro
#define iterate_tuple_fname_back iterate_tuple_fname##_back
Since iterate_tuple_fname is not a parameter of this macro, no early replacement occurs for iterate_tuple_fname. The whole thing is immediately concatenated into iterate_tuple_fname_back and only after that it is rescanned. But rescan finds nothing to replace there, so iterate_tuple_fname_back is the final result.
If you want the preprocessor to replace the left-hand side of the ## operator (which was your intent apparently), you absolutely have to use a macro parameter on the left-hand side, as in
#define ITF_back(prefix) prefix##_back
and then you can use this macro as
ITF_back(iterate_tuple_fname)
Now the rescan and recursive replacement inside iterate_tuple_fname will occur early, before the concatenation with the _back part. I.e. it will work as you wanted it to.
What does the following statement mean:
#define FAHAD
I am familiar with the statements like:
#define FAHAD 1
But what does the #define statement without a token signify?
Is it that it is similar to a constant definition?
Defining a constant without a value acts as a flag to the preprocessor, and can be used like so:
#define MY_FLAG
#ifdef MY_FLAG
/* If we defined MY_FLAG, we want this to be compiled */
#else
/* We did not define MY_FLAG, we want this to be compiled instead */
#endif
it means that FAHAD is defined, you can later check if it's defined or not with:
#ifdef FAHAD
//do something
#else
//something else
#endif
Or:
#ifndef FAHAD //if not defined
//do something
#endif
A real life example use is to check if a function or a header is available for your platform, usually a build system will define macros to indicate that some functions or headers exist before actually compiling, for example this checks if signal.h is available:
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif/*HAVE_SIGNAL_H*/
This checks if some function is available
#ifdef HAVE_SOME_FUNCTION
//use this function
#else
//else use another one
#endif
Any #define results in replacing the original identifier with the replacement tokens. If there are no replacement tokens, the replacement is empty:
#define DEF_A "some stuff"
#define DEF_B 42
#define DEF_C
printf("%s is %d\n", DEF_A, DEF_B DEF_C);
expands to:
printf("%s is %d\n", "some stuff", 42 );
I put a space between 42 and ) to indicate the "nothing" that DEF_C expanded-to, but in terms of the language at least, the output of the preprocessor is merely a stream of tokens. (Actual compilers generally let you see the preprocessor output. Whether there will be any white-space here depends on the actual preprocessor. For GNU cpp, there is one.)
As in the other answers so far, you can use #ifdef to test whether an identifier has been #defined. You can also write:
#if defined(DEF_C)
for instance. These tests are positive (i.e., the identifier is defined) even if the expansion is empty.
#define FAHAD
this will act like a compiler flag, under which some code can be done.
this will instruct the compiler to compile the code present under this compiler option
#ifdef FAHAD
printf();
#else
/* NA */
#endif
I regularly use object-like preprocessor macros as boolean flags in C code to turn on and off sections of code.
For example
#define DEBUG_PRINT 1
And then use it like
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
However, it comes a problem if the header file that contains the #define is forgotten to be included in the source code. Since the macro is not declared, the preprocessor treats it as if it equals 0, and the #if statement never runs.
When the header file is forgotten to be included, non-expected, unruly behaviour can occur.
Ideally, I would like to be able to both check that a macro is defined, and check that it equals a certain value, in one line. If it is not defined, the preprocessor throws an error (or warning).
I'm looking for something along the lines of:
#if-def-and-true-else-throw-error(DEBUG_PRINT)
...
#endif
It's like a combination of #ifdef and #if, and if it doesn't exist, uses #error.
I have explored a few avenues, however, preprocessor directives can't be used inside a #define block, and as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
This may not work for the general case (I don't think there's a general solution to what you're asking for), but for your specific example you might consider changing this sequence of code:
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
to:
if (DEBUG_PRINT == 1) {
printf("%s", "Testing");
}
It's no more verbose and will fail to compile if DEBUG_PRINT is not defined or if it's defined to be something that cannot be compared with 1.
as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
It can't be an error because the C standard specifies that behavior is legal. From section 6.10.1/3 of ISO C99 standard:
After all replacements due to macro expansion and the defined unary
operator have been performed, all remaining identifiers are replaced with the pp-number
0....
As Jim Balter notes in the comment below, though, some compilers (such as gcc) can issue warnings about it. However, since the behavior of substituting 0 for unrecognized preprocessor tokens is legal (and in many cases desirable), I'd expect that enabling such warnings in practice would generate a significant amount of noise.
There's no way to do exactly what you want. If you want to generate a compilation failure if the macro is not defined, you'll have to do it explicitly
#if !defined DEBUG_PRINT
#error DEBUG_PRINT is not defined.
#endif
for each source file that cares. Alternatively, you could convert your macro to a function-like macro and avoid using #if. For example, you could define a DEBUG_PRINT macro that expands to a printf call for debug builds but expands to nothing for non-debug builds. Any file that neglects to include the header defining the macro then would fail to compile.
Edit:
Regarding desirability, I have seen numerous times where code uses:
#if ENABLE_SOME_CODE
...
#endif
instead of:
#ifdef ENABLE_SOME_CODE
...
#endif
so that #define ENABLE_SOME_CODE 0 disables the code rather than enables it.
Rather than using DEBUG_PRINT directly in your source files, put this in the header file:
#if !defined(DEBUG_PRINT)
#error DEBUG_PRINT is not defined
#endif
#if DEBUG_PRINT
#define PrintDebug([args]) [definition]
#else
#define PrintDebug
#endif
Any source file that uses PrintDebug but doesn't include the header file will fail to compile.
If you need other code than calls to PrintDebug to be compiled based on DEBUG_PRINT, consider using Michael Burr's suggestion of using plain if rather than #if (yes, the optimizer will not generate code within a false constant test).
Edit:
And you can generalize PrintDebug above to include or exclude arbitrary code as long as you don't have commas that look like macro arguments:
#if !defined(IF_DEBUG)
#error IF_DEBUG is not defined
#endif
#if IF_DEBUG
#define IfDebug(code) code
#else
#define IfDebug(code)
#endif
Then you can write stuff like
IfDebug(int count1;) // IfDebug(int count1, count2;) won't work
IfDebug(int count2;)
...
IfDebug(count1++; count2++;)
Yes you can check both:
#if defined DEBUG && DEBUG == 1
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
In this example even when #define DEBUG 0 but it is not equal to 1 thus nothing will be printed.
You can do even this:
#if defined DEBUG && DEBUG
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
Here if you #define DEBUG 0 and then D(1,2,3) also nothing will be printed
DOC
Simply create a macro DEBUG_PRINT that does the actual printing:
#define DEBUG_PRINT(n, str) \
\
if(n == 1) \
{ \
printf("%s", str); \
} \
else if(n == 2) \
{ \
do_something_else(); \
} \
\
#endif
#include <stdio.h>
int main()
{
DEBUG_PRINT(1, "testing");
}
If the macro isn't defined, then you will get a compiler error because the symbol is not recognized.
#if 0 // 0/1
#define DEBUG_PRINT printf("%s", "Testing")
#else
#define DEBUG_PRINT printf("%s")
#endif
So when "if 0" it'll do nothing and when "if 1" it'll execute the defined macro.