Why doesn't #if preprocessor work? - c

With the following code, I always get "VGA" as output ,when I intend to get "NOT VGA"
#include<stdio.h>
#include<conio.h>
#define ADAPTER NVGA
#if ADAPTER==VGA
int main()
{
printf("VGA");
getch();
return 0;
}
#else
int main()
{
printf(" NOT VGA");
getch();
return 0;
}
#endif

Question is, where are VGA and NVGA defined?
If they are not defined, they will equal 0 according to C standard (N1570 - 6.10.1 Conditional inclusion - paragraph 4):
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.
Which means your comparison will be #if 0==0, which is identical to #if 1.
To fix this, you need to define both VGA and NVGA to have different values:
#define VGA 1
#define NVGA 2

There are two possibilities, and I can't tell which. The most likely is that, because neither NVGA nor VGA is a #defined macro, they are both evaluated as zero in #if and therefore considered to be equal. (This is a rule of the language.) The second possibility is that your system's stdio.h or conio.h defines NVGA to VGA.
To find out which, compile this program and see what happens:
#include <stdio.h>
#include <conio.h>
/* these numbers are chosen at random */
#define NVGA 8446
#define VGA 13060
#define ADAPTER NVGA
int main(void)
{
#if ADAPTER == VGA
puts("VGA");
#else
puts("NOT VGA");
#endif
getch();
return 0;
}
If it produces the output you expected (i.e. "NOT VGA"), your problem is the first one. If you get an error about redefining NVGA or VGA, your problem is the second one.

Because NVGA itself hasn't been defined. Instead try this:
#define NVGA 0
#define VGA 1
#define ADAPTER VGA
#if ADAPTER==VGA
/* insert VGA code here*/
#else
/* insert NVGA code here*/
#endif

Related

In C macros, where does the function named defined() come from?

In the code below, I don't understand the defined() function used inside #if; where is it defined?
Can anyone point me to a good resource in C language, where I could go deeper in these kinds of kinds of stuff?
#include <stdio.h>
#define Macro 7
void initMSP(void){
printf("OKay with MSP platform\n");
}
void initKine(void){
printf("Done with Kine\n");
}
//#define KINETICS
#define MSP
int main(){
printf("Hello world program\n");
printf("%d\n",Macro);
#if defined(KINETICS) && !defined(MSP)
initKine();
#elif defined(MSP) && !defined(KINETICS)
initMSP();
#else
#error "Please define a Platform "
#endif
}
defined is not a function. It is a syntactic construct of the C preprocessor, just like #define, #ifdef, and so forth. The C language proper (to the extent that you can divorce C from its preprocessor) never directly interacts with defined. It exists during preprocessing and that's that.

error C2003: expected 'defined id'

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;
}

What does the c precompiler do with macros defined as (void)0

I have some macros that are defined based on compiler flags. I'm trying to decide whether I would rather have the macro defined as (void)0 or have it undefined and cause a compile time error.
i.e.
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) (void)0
#endif
int main(void) {
...
PRINTF("something");
...
}
vs.
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#endif
int main(void) {
...
#ifdef DEBUG
PRINTF("something");
#endif
...
}
I'm not sure which technique I prefer. On one hand wrapping every PRINTF statement with #ifdef's would be ugly. On the other hand it would be nice to know at compile time if I've called a function that doesn't really work in the context.
I think the deciding factor will be whether or not having the (void)0 macros is going to affect the size of the executable.
When the code is compiled, what happens to the (void)0's? If PRINTF is defined as (void)0, does that mean the executable is going to contain some sort of (void)0 instruction or will it be completely ignored?
(void) 0;
is an expression statement with no side-effect. Any sane implementation will optimize this statement out (what else an implementation could do with such a statement?).
Having (void) 0 as a macro definition is endorsed by the C Standard as it appears in (C11) 7.2p1 for assert macro definition if NDEBUG is defined:
#define assert(ignore) ((void)0)
Note that defining:
#define PRINTF(...) (void)0
instead of
#define PRINTF(...)
has an advantage. In the first case, you have an expression (like a function that returns no value) and so it is usable for example in a comma expression or in a conditional expression.
For example:
// Comma expression
printf("test"), PRINTF("Hi Dennis");
// Conditional expression
test-expr ? perror("Hello") : PRINTF("world");
This two expression statements are only valid with the former PRINTF definition (with (void) 0).
It'll be completely ignored, you can confirm this by looking at the assembly output (gcc -S will generate file.s, the asm output), compare with and without the (void)0 line and see that it is completely the same.
A half way decent compiler will optimise away dead (unreachable) code, so you can:
#ifdef DEBUG
#define PRINTF(...) if (1) { printf(__VA_ARGS__) ; }
#else
#define PRINTF(...) if (0) { printf(__VA_ARGS__) ; }
#endif
which has the big advantage of allowing the compiler to check the debug code, no matter whether you are working with/without your DEBUG turned on -- which reduces the risk of ending up with painful teeth marks in your backside.

#define IDENTIFIER without a token

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

Correct #if functionality

If I define
#if SOMETHING
#endif
and I have not defined SOMETHING anywhere. Would the code inside #if compile ?
When the name used in the argument expression of #if is not defined as a macro (after all other macro replacement is finished), it is replaced with 0. This means that your #if SOMETHING will be interpreted as #if 0. The code under #if will be removed by preprocessor.
The rule applies to more complex expressions as well. You can do
#define A 42
#if A + B
which will evaluate to #if 42, since unknown name B is interpreted as 0
No, as long as SOMETHING is also not one of the predfined macros or a macro passed on the commandline to the compiler.
I think in C99 it defaults to 0 while in C89 it does not as here its giving me an error
Source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define A 42
#define B
int main(int argc, char *argv[]){
int c;
#if A
c = A + B;
#endif
printf("%d\n",c);
return 0;
}
Error :
error: expected expression before ‘;’ token
No, because as an undefined macro, it would not necessarily be replaced with anything... but that is probably compiler specifc, and not to be trusted.
You may want to use:
#ifdef DEFINED_WORD
#ifndef DEFINED_WORD
Where DEFINED_WORD is declared by a #define, like: #define DEFINED_WORD. The ifdef construct ONLY compiles the code between that and the #endif if DEFINED_WORD was defined. The opposite is true of #ifndef. You can nest them like so:
#ifdef DEFINED_WORD
printf ( "DEFINED_WORD is defined\n" );
#ifndef DEFINED_WORD
printf ( "This line will NEVER print\n" );
#endif
printf ( "This line will print if DEFINED_WORD is defined\n" );
#endif
printf ( "This line will ALWAYS print.\n" );
In my code, I have constructs like:
#ifdef DEBUG
printf ( "array[%d] = %d\n", i, array[i] );
#endif
To deactivate all of the DEBUG code, just comment out the line that you MUST have before calling that #ifdef (top of the source file, or in an included header which you included at the top of the source file, in good form). #define DEBUG
Hope that helps.

Resources