Correct #if functionality - c

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.

Related

Check if Pre processor Directive is defined in C Programming [duplicate]

Based on this question How to catch empty defined macro with gcc? I have another problem. How to catch undefined macro in preprocessor #if condition? Example code:
#include <stdio.h>
int main()
{
#if ENABLE_SOMETHING == 1
... do something ..
#endif
return 0;
}
Is there a way to catch error/warning when ENABLE_SOMETHING is not set using gcc compiler(maybe some flag)? Or maybe there are external tools which I can use?
I know than i can write something like this :
#ifndef ENABLE_SOMETHING
#error "ENABLE_SOMETHING undefined!"
#endif
But I have a huge amount of different defines(ENABLE_STH1, ENABLE_STH2, ENALBE_STH3 ... etc.) in code and i don't want to fix this manually. I'm looking for some automatic solution for our project.
Is there a way to catch error/warning when ENABLE_SOMETHING is not set
using gcc compiler(maybe some flag)?
With GCC you can use the -Wundef flag.
From the official documentation
-Wundef
Warn if an undefined identifier is evaluated in an #if directive. Such identifiers are replaced with zero.
EDIT:
For example, this C-code:
#include <stdio.h>
int main(void)
{
#if UNDEFINED_MACRO
printf("hi mum!\n");
#endif
return 0;
}
... compiled with GCC and the -Wundef flag yields this:
$ gcc undef.c -Wundef
undef.c: In function 'main':
undef.c:5:5: warning: "UNDEFINED_MACRO" is not defined [-Wundef]
#if UNDEFINED_MACRO
^
Let's assume you have this code and it compiles, but you don't know if MAX_N_LENGTH is a macro, or if it's something else:
int main()
{
int a = MAX_N_LENGTH; // MAX_N_LENGTH could also be an int declared somewhere else
return 0;
}
You can check whether it actually is a macro like this:
#ifdef MAX_N_LENGTH
printf("MAX_N_LENGTH is a macro.\n");
#else
printf("MAX_N_LENGTH is NOT macro.\n");
#endif // MAX_N_LENGTH
Of course, if that ever is an issue, I'd rethink my naming conventions.
You could try something like the following:
#ifndef MAX_N_LENGTH
#warning "MAX_N_LENGTH is undefined"
int array[16];
#else
int array[MAX_N_LENGTH + 1];
#endif
You can test if a macro is defined in a #if preprocessor expression with defined(ENABLE_SOMETHING):
#if !defined(ENABLE_SOMETHING)
#error ENABLE_SOMETHING is not defined
#endif
You can handle macros with an empty definition this way:
#if ENABLE_SOMETHING + 0 == 1
/* ENABLE_SOMETHING is defined and not 0 or empty */
#endif

How to catch undefined macro in preprocessor #if condition?

Based on this question How to catch empty defined macro with gcc? I have another problem. How to catch undefined macro in preprocessor #if condition? Example code:
#include <stdio.h>
int main()
{
#if ENABLE_SOMETHING == 1
... do something ..
#endif
return 0;
}
Is there a way to catch error/warning when ENABLE_SOMETHING is not set using gcc compiler(maybe some flag)? Or maybe there are external tools which I can use?
I know than i can write something like this :
#ifndef ENABLE_SOMETHING
#error "ENABLE_SOMETHING undefined!"
#endif
But I have a huge amount of different defines(ENABLE_STH1, ENABLE_STH2, ENALBE_STH3 ... etc.) in code and i don't want to fix this manually. I'm looking for some automatic solution for our project.
Is there a way to catch error/warning when ENABLE_SOMETHING is not set
using gcc compiler(maybe some flag)?
With GCC you can use the -Wundef flag.
From the official documentation
-Wundef
Warn if an undefined identifier is evaluated in an #if directive. Such identifiers are replaced with zero.
EDIT:
For example, this C-code:
#include <stdio.h>
int main(void)
{
#if UNDEFINED_MACRO
printf("hi mum!\n");
#endif
return 0;
}
... compiled with GCC and the -Wundef flag yields this:
$ gcc undef.c -Wundef
undef.c: In function 'main':
undef.c:5:5: warning: "UNDEFINED_MACRO" is not defined [-Wundef]
#if UNDEFINED_MACRO
^
Let's assume you have this code and it compiles, but you don't know if MAX_N_LENGTH is a macro, or if it's something else:
int main()
{
int a = MAX_N_LENGTH; // MAX_N_LENGTH could also be an int declared somewhere else
return 0;
}
You can check whether it actually is a macro like this:
#ifdef MAX_N_LENGTH
printf("MAX_N_LENGTH is a macro.\n");
#else
printf("MAX_N_LENGTH is NOT macro.\n");
#endif // MAX_N_LENGTH
Of course, if that ever is an issue, I'd rethink my naming conventions.
You could try something like the following:
#ifndef MAX_N_LENGTH
#warning "MAX_N_LENGTH is undefined"
int array[16];
#else
int array[MAX_N_LENGTH + 1];
#endif
You can test if a macro is defined in a #if preprocessor expression with defined(ENABLE_SOMETHING):
#if !defined(ENABLE_SOMETHING)
#error ENABLE_SOMETHING is not defined
#endif
You can handle macros with an empty definition this way:
#if ENABLE_SOMETHING + 0 == 1
/* ENABLE_SOMETHING is defined and not 0 or empty */
#endif

Asterisk in the argument name with C preprocessor

I want to implement cross-platform build of my DLL with mingw32/VC.
At the moment everything is perfect with mingw side. However I have to wrap several things in macro for VC (it is built as /TC), for example:
void __attribute__((fastcall)) do1 ( A*, B , C, D );
bool __attribute__((fastcall)) ( *do2 ) ( E*, F );
The first one is simple, just a macro:
#ifdef __MINGW32__
#define __FASTCALL__ __attribute__((fastcall))
#elif _MSC_VER
#define __FASTCALL__ __fastcall
#else
#error "unsupported compiler"
#endif
The problem comes with the second one. Calling convention with a function pointer should looks like
bool ( __fastcall *do2 ) ( E*, F );
I tried the following macro (I skipped ifdef part):
#define __FASTCALLP__(func) (__attribute__((fastcall))(*##func))
#define __FASTCALLP__(func) (__fastcall *##func)
or if pass function name with asterisk:
#define __FASTCALLP__(func) (__attribute__((fastcall))(##func))
#define __FASTCALLP__(func) (__fastcall ##func)
Both failed with
error: pasting "*" and "function_name" does not give a valid
preprocessing token
May I wrong at my approach at all? Or I have to ifdef the whole code blocks or separate it to different files?
The problem is with the Concatenation-Operator ##. It will produce a new preprocessor token by concatenating the left- and right-hand-side, which does not exists (*do2 is no defined token)
Simply omit it and write like this (omitting #ifdefs):
#define __FASTCALL__(func) (__attribute__((fastcall))(func))
#define __FASTCALL__(func) (__fastcall func)
and use like this:
bool __FASTCALL__(do1)(A*, B , C, D);
bool __FASTCALL__(*do2)(E*, F);

Why doesn't #if preprocessor work?

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

#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

Resources