Conditional compilation error with macros - c

#include<stdio.h>
#define NUM 10
main()
{
#ifdef NUM
printf("compilation succesfull");
#endif
}
The above code compiles perfectly fine and upon execution prints
compilation successful, but if I remove a blank line before the first statement in main()
it gives an error. ie. "stray #" in the program and many other errors.
#include<stdio.h>
#define NUM 10
main()
{ #ifdef NUM
printf("compilation succesfull");
#endif
}
Can any one help me?

Preprocessor statements need to be on their own lines. So you can't put it on the same line as a { or anything else that's not part of the statement.

The preprocessor is unable to understand the line:
{ #ifdef NUM
The compiler doesn't know how to handle the statement #ifdef NUM, it'll say # is unknown and unknown type ifdef.
it'll reach the line
#endif
but didn't see ifdef before, thus you'll get #endif without #if error.
When you replace it in a new line, then the preprocessor knows what to do and the output will be:
main()
{
printf("compilation succesfull");
}
Validate this by running gcc -E yourprogram.

The Tag #ifdef you are using is correct. In the C language, lines that start with # in the code are called preprocessor directives. The preprocessor deletes them and uses them as commands to modify the code file prior to compilation.
For such statement for preprocessor, it should start in a new line, and only white space is allowed before the #. You should not put it after {.
For your code, compiler will like it, if it could be arranged as following.
#include<stdio.h>
#define NUM 10
main()
{
#ifdef NUM
printf("compilation succesfull");
#endif
}

Related

Conditional execution not working for this case of code?

Why the code inside the #ifdef INITIALISATION and #endif is not executed?
int main(void)
{
uint8_t DLEVEL = 10;
#if DLEVEL > 5
#define INITIALISATION
#endif
while (1)
{
#ifdef INITIALISATION
Display(); // This line is never being executing :: please help for a solution
#endif
}
}
edited...
Thanks for the reply
Actually the below mentioned logic of the code is used as a part of my code memory optimization.
Now the code memory size is overflowed, so i need to execute the one time initializations when the SYM_DLEVEL value is 10 and then the value of SYM_DLEVEL is changed from 10 to 2, then the initial sections i need to be automatically commented or disabled and then only the Display_2() function needed to be enable and need to execute.
Is it possible?
#define SYM_DLEVEL 10
int main(void)
{
#if SYM_DLEVEL > 5
Display_1(); // need to execute this line once(before the value changes from 10 t0 2)
#endif
#define SYM_DLEVEL 2 // after this line execution i need to automatically disable the above section and automatically enable the below section
#if SYM_DLEVEL < 5
#define INITIALISATION // need to execute only when value changes from 10 to 2
#endif
while (1)
{
#ifdef INITIALISATION
Display_2();
#endif
}
}
It doesn't execute code because the preprocessor runs in the compiler, while the local variable DLEVEL is assigned during execution.
The preprocessor simply looks for a preprocessor symbol DLEVEL that evidently is undefined.
Undefined symbols are equated to 0, so the symbol INITIALISATION isn't defined.
To make it work define a preprocessor symbol, i.e. SYM_DLEVEL, to be used in the conditional preprocessing, and eventually assign it to the runtime variable. I.e.
#define SYM_DLEVEL 10
int main(void)
{
uint8_t DLEVEL = SYM_DLEVEL;
#if SYM_DLEVEL > 5
#define INITIALISATION
#endif
while (1)
{
#ifdef INITIALISATION
Display(); // This line is now is executed
#endif
}
}
Remember that preprocessing is more or less a text processor (which actuates on base piece of text, tokens, as outlined in comments below), and is executed before the compilation of the code. It doesn't know about runtime variables and their assignments, it only knows symbols defined with a preprocessor directive (#define).
Don't confuse actions as dead code removal or other optimization made by compiler with what the preprocessor can do. The golden rule is: "preprocessing only understand preprocessing objects, C code is a plain text without any special meaning for it".

Is there a way to expand macro based on command line arguments? [duplicate]

Following program compiles successfully and print 1000 without even calling a foo() function from our main() function. How is it possible?
#include<stdio.h>
void foo()
{
#define ans 1000
}
int main() {
printf("%d", ans);
return 0;
}
#defineis run by the preprocessor which is staged before the compiler. After the preprocessor is done, the code will look like this:
/* Everything that is inside stdio.h is inserted here */
void foo()
{
}
int main() {
printf("%d", 1000);
return 0;
}
And this is what actually get compiled.
The preprocessor is very important to make header files work. In them, you see this structure:
#ifndef foo
#define foo
/* The content of the header file */
#endif
Without this, the compiler would complain if a header file is included more than once. You may ask why you would want to include a header file more than once. Well, header files can include other header files. Consider this macro, which is useful for debugging. It prints the name of the variable and then the value. Note that you would have to do a separate version for different types.
#define dbg_print_int(x) fprintf(stderr, "%s = %d", #x, x)
This is pretty versatile, so you may want to include it in a header file for own use. Since it requires stdio.h, we include it.
/* debug.h */
#include <stdio.h>
#define dbg_print_int(x) fprintf(stderr, "%s = %d", #x, x)
What happens when you include this file and also include stdio.h in you main program? Well, stdio.h will be included twice. That's why debug.h should look like this:
/* debug.h */
#ifndef DEBUG_H
#define DEBUG_H
#include <stdio.h>
#define dbg_print_int(x) fprintf(stderr, "%s = %d", #x, x)
#endif
The file stdio.h has the same construct. The main thing here is that this is run before the compiler. The define is a simple replacement command. It does not know anything about scope or types. However, as you can see here, there is some basic logic built into it. Another thing that the preprocessor does is to remove all the comments.
You can read more about the C preprocessor here: http://www.tutorialspoint.com/cprogramming/c_preprocessors.htm
The #define is processed by the preprocessor before the compiler does anything. It is a simple text replacement. The preprocessor doesn't even know if the line of code is inside or outside a function, class or whatever [Ref: https://stackoverflow.com/a/36968600/5505997]. Clearly you do not need to call the function to set the value and obviously you will not get any error during compile.
As others have stated, #define is a preprocessor directive, not C source code. See Wiki here.
Point being, in your code #define ans 1000 is not a variable definition, meaning that even if you were calling foo() in the main, you would still not be setting "ans" at runtime, because it is simply not a variable. It is just telling the preprocessor what to do with the "label" "ans", when it finds it in your source code.
In this example, the main() will essentially be calling an empty foo() function:
int main()
{
foo(); // Calls an empty function
printf("%d", ans); // ans will have been substituted by 1000 by the time you start executing you code
return 0;
}
The definition of "ans" will simpy not exist anymore by the time you start executing you main(). This is what the preprocessor does (in part). It finds all the #defines declared in your entire source code and tries to find places in your code where you have used these defines. If you have not used them, it moves on (don't care), if you have, it substitutes the label by the actual defined value.

Stripping specific functions on compile time

I'm writing a C program that uses a custom logging function to debug my program. Whenever I compile my program as a release version, I want all of my logging functions to be stripped from the code so it won't show up if someone tries to disassemble it.
Take the following example:
#include <stdio.h>
void custom_logging_function(char* message)
{
// Do something here
}
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
How could I make it so that the custom_logging_function and it's arguments aren't compiled into my program without having to write include guards everywhere throughout my code? Thank you
You can use pre-processor flags, for example:
#include <stdio.h>
#ifdef DEBUG
void custom_logging_function(char* message)
{
// Do something here
}
#else
#define custom_logging_function(x) ((void) 0)
#endif
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
With this code you will have to tell the "debug" target to define DEBUG, if you want to define something specifically for the "release" target you can replace #ifdef DEBUG with #ifndef NDEBUG and add the NDEBUG flag to the "release" definitions.
Edit:
Changed #define custom_logging_function(x) 0 to #define custom_logging_function(x) ((void) 0) inspired by #JoachimPileborg his answer.
Assuming you only want the logging calls to happen in a debug-build of your application, and not the release build you send to customers, you can still use the preprocessor and conditional compilation for it. It can be made vert simple though by using macros instead of having checks at every call.
Something like this in a heder file:
#ifdef _DEBUG
void custom_logging_function(char* message);
#else
# define custom_logging_function(message) ((void) 0)
#endif
You could use an empty macro body for the release-macro, but that can cause some compilers to give "empty statement" warnings. Instead I use an expression casted to void (to tell the compiler that the result of the expression will not be used). Any smart compiler will not include the expression after optimization.

How gets an #if Preprocessor conditional which contains a variable resolved without producing an error?

How does an #if Preprocessor stage statement which contain variable of compile time get resolved at preprocessor stage itself?
Below is the code which runs without any error:
#include<stdio.h>
void main()
{
int num=10; /* compile time */
#if((num%2)==0) /* #if is preprocessor stage but has num of compile time why not error here? */
printf("\nNumber is Even");
#else
printf("\nNumber is Odd");
#endif
}
For the evaluation in #if, the preprocessor replaces all identifiers that are already defined macros by their appropriate expansion. All identifiers that remain after that have the value 0.

Define constant inside #ifdef in C

I want to define a constant depending on the OS in use.
As such:
#include <stdio.h>
#ifdef _Win32 //Used for system("cls") command
#include <process.h>
#define CLEAR "system(\"cls\")"
#endif
#ifdef __APPLE__
#define CLEAR "system(\"clear\")"
#endif
int main()
{
CLEAR;
}
Xcode gives me an error stating that expression result unused at
#define CLEAR "system(\"clear\") and inside the main function.
I am on a Mac.
Use:
#define CLEAR system("clear")
not
#define CLEAR "system(\"clear\")"
You get the error because your macro call is substituted with:
"system(\"clear\")";
which is a useless expression statement (the expression being the string here) like for example:
0; // valid but pointless
try altering your main function as such:
int main()
{
int rc;
rc = CLEAR;
return rc;
}
You need to catch the return value of the system() call and use it
#define CLEAR system("clear")
and not
#define CLEAR "system(\"clear\")"
The compiler will create a new C code (called pre-processor code) in which will replace the macro name by its content.
so if you define macro in this way:
#define CLEAR "system(\"clear\")"
You will get in the new code (pre-processor code) generated by the Compiler:
int main()
{
"system(\"clear\")";
}
You can see the code generated by the compiler (pre-processor code) with gcc -E

Resources