What is difference between preprocessor directive #if and normal if in C? I'm new to C.
Statements with # in front of them are called preprocessor directives. They are processed by a parser before the code is actually compiled. From the first search hit using Google (http://www.cplusplus.com/doc/tutorial/preprocessor/):
Preprocessor directives are lines included in the code of our programs that are not program statements but directives for the preprocessor. These lines are always preceded by a hash sign (#). The preprocessor is executed before the actual compilation of code begins, therefore the preprocessor digests all these directives before any code is generated by the statements.
So a #if will be decided at compile time, a "normal" if will be decided at run time. In other words,
#define TEST 1
#if TEST
printf("%d", TEST);
#endif
Will compile as
printf("%d", 1);
If instead you wrote
#define TEST 1
if(TEST)
printf("%d", TEST);
The program would actually compile as
if(1)
printf("%d", 1);
Preprocessor if allows you to condition the code before it's sent to the compiler. Often used to stop header code from being added twice.
edit, did you mean C++, because it was tagged as such?
http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor/
The preprocessor if is handled by the preprocessor as the first step in the program being compiled. The normal if is handled at runtime when the program is executed. The preprocessor directive is used to enable conditional compilation, using different sections of the code depending on different defined preprocessor constants/expressions. The normal if is used to control flow in the executing program.
Related
Is it mandatory to write #include at the top of the program and outside the main function?
I tried using #define preprocessor inside the main function and it worked fine with only one exception..that being the constant which i defined using the define directive can be used only after the line #define
For instance say printf("%d",PI); #define PI 3.14will give error "Undefined symbol PI". But in the following code i did not encounter any error
#define PI 3.14
printf("%d",PI);
Is this because C is a procedural language and procedural languages implements top down approach?
Also i would like to know that can we use only #define inside the main function or other preprocessor directives too? If we can use then which ones?
Or is it the other way around, instead of #include we can use all the preprocessor directives in the main function?
The only place you can't put a preprocessor directive is in a macro expansion. The sole exception is #pragma, which can also be written _Pragma().
This has nothing to do with "procedural", but due to the fact that C is defined in terms of 8 translation phases, each of which is "as-if" fully-completed before the next phase. For more details, see the C11 standard, section 5.1.1.2.
One example of when it is useful to use preprocessor directives after the start of a file is for the "X Macro" technique (which many people only know as "those .def files").
Preprocessor directives work pretty much anywhere. Of course, you can make your code confusing pretty easily if you abuse this.
The pre-processor does its work before the compiler performs the source code translation into object code. Pre-processing is mostly a string replacement task, so it can be placed just about anywhere in your code. Of course, if the resulting expansion is syntactically incorrect, the expanded source code will fail to compile.
A commonly tolerated practice is to embed conditional compilation directives inside a function to allow the function to use platform specific APIs.
void some_wrapper_function () {
#if defined(UNIX)
some_unix_specific_function();
#elif defined(WIN32)
some_win32_specific_function();
#else
#error "Compiled on an unsupported platform"
#endif
}
By their nature, the directives themselves normally have to be defined at the beginning of the line, and not somewhere in the middle of source line. But, defined macros can of course appear anywhere in the source, and will be replaced according to the substitution rules defined by your directives.
The trick here is to realize that # directives have traditionally been interpreted by a pre-processor, that runs before any compilation. The pre-processor would produce a new source file, which was then compiled. I don't think any modern compiler works that way by default, but the same principles apply.
So when you say
#include "foo.h"
you're saying "insert the entire contents of foo.h into my source code starting at this line."
You can use this directive pretty much anywhere in a source file, but it's rarely useful (and not often readable) to use it anywhere other than at the start of the source.
I am trying to understand the idea of function like Macros however there are a few points that befuddle me. For example say we have:
#define Max(a,b) ((a)>(b)) ? (a):(b))
and I call it like such
int i = Max(4,5);
This will evaluate a conditional expression equivalent to a>b? If yes then a, else b. But I'm confused as to how the Max function knows what to do with the arguments. Unlike an actual function, the implementation isn't written in code in the calling program. is the statement to the right of the define statement doing this for me? Its just a new thing for me and I want to make sure I understand what is happening here.
This particular part of function like macros confuses me. I know that these types of macros are useful for reducing overhead costs since they exclude the JSR RTS processor instructions which saves memory on the stack.
#define Max(a,b) ((a)>(b)) ? (a):(b))
is a macro, that causes nothing else but a simple textual replacement within your code, which means that during the preprocessing this line:
int i = Max(4,5);
is changed into:
int i = ((4)>(5)) ? (4):(5));
Note that there is no type safety while working with macros like this one and you will have really hard time while debugging your code as well. Good rule of thumb is: Don't use macro when you can achieve the same with function:
int max(int a, int b) {
return (a > b) ? a : b;
}
What the compiler actually sees, after preprocessing, is:
int i = ((4)>(5)) ? (4):(5));
The parameters passed to the macro are substituted into the body of the macro.
Just stop thinking about macro like compilable code. Macros are "resolved" by pre-processor, not actually during compilation stage. So by macro definitions you just define how to process certain string in text file. Only output of pre-processor is passed to compiler. You can use gcc -E to see your source after pre-processor. It is still C code on this stage but without any preprocessor directive.
Hope this will help you.
try to build your code with the gcc -E and see how your code look before compiling it
In fact in the build process the compilator transform your actual code to a preprocessor code.
In the preprocessor phase the compilator replace all macro in your c code with its content and generate another code called preprocessor code and then the compilateor generate the object code from the preprocessor code
The gcc -E allow you to see your preprocessor code
I added this in my code:
#ifdef DEBUG_MODE
printf("i=%d\n",i);
fflush(stdout);
#endif
and my question is, if I'm not in DEBUG_MODE what the compiler does when compiling this?
The compiler will do nothing, because there will be nothing there when DEBUG_MODE is not defined.
#ifdef and #endif control conditional compilation. This happens during an initial pass over the program, making dumb textual substitutions before the compiler even begins to consider the file to contain C code specifically. In this case, without the symbol defined only whitespace is left. The text is never even lexed into C tokens if the preprocessor define tested for isn't defined at that point.
You can see this for yourself: just invoke your compiler with whatever flag it uses to stop after preprocessing - e.g. gcc -E x.cc - and at that point in the output there will just be an empty line or two. This is also a very important technique for understanding macros, and a good thing to do when you just can't guess why some program's not working the way you expect - the compiler says some class or function doesn't exist and you've included its header - look at the preprocessed output to know what your compiler is really dealing with.
if DEBUG_MODE is not defined, the code under it will not be compiled.
If I write
#include <stdio.h>;
there no error but a warning comes out during compilation
pari.c:1:18: warning: extra tokens at end of #include directive
What is the reason ?
The reason is that preprocessor directives don't use semicolons. This is because they use a line break to delimit statements. This means that you cannot have multiple directives per line:
#define ABC #define DEF // illegal
But you can have one on multiple lines by ending each line (except the last) with a \ (or /, I forget).
Because Preprocessor directives are lines included in the code of our programs that are not program statements but directives for the preprocessor.
These preprocessor directives extend only across a single line of code. As soon as a newline character is found, the preprocessor directive is considered to end. That's why no semicolon (;) is expected at the end of a preprocessor directive.
Preprocessor directives are a different language than C, and have a much simpler grammar, because originally they were "parsed", if you can call it that, by a different program called cpp before the C compiler saw the file. People could use that to pre-process even non-C files to include conditional parts of config files and the like.
There is a Linux program called "unifdef" that you can still use to remove some of the conditional parts of a program if you know they'll never be true. For instance, if you have some code to support non-ANSI standard compilers surrounded by #ifdef ANSI/#else/#end or just #ifndef ANSI/#end, and you know you'll never have to support non-ANSI any more, you can eliminate the dead code by running it through unifdef -DANSI.
Because they're unnecessary. Preprocessor directives only exist on one line, unless you explicitly use a line-continuation character (for e.g. a big macro).
During compilation, your code is processed by two separate programs, the pre-processor and the compiler. The pre-processor runs first.
Your code is actually comprised of two languages, one overlaid on top of another. The pre-processor deals with one language, which is all directives starting with "#" (and the implications of these directives). It processes the "#include", "#define" and other directives, and leaves the rest of the code untouched (well, except as side effect of the pre-processor directives, like macro substitutions etc.).
Then the compiler comes along and processes the output generated by the pre-processor. It deals with "C" language, and pretty much ignores the pre-processor directives.
The answer to your question is that "#include" is a part of the language processed by the pre-processor, and in this language ";" are not required, and are, in fact, "extra tokens".
and if you use #define MACRO(para) fun(para); it could be WRONG to put an semikolon behind it.
if (cond)
MACRO (par1);
else
MACRO (par2);
leads to an syntactical error
What is the function of #?
It denotes a preprocessor directive:
One important thing you need to remember is that the C preprocessor is not part of the C compiler.
The C preprocessor uses a different syntax. All directives in the C preprocessor begin with a pound sign (#). In other words, the pound sign denotes the beginning of a preprocessor directive, and it must be the first nonspace character on the line.
# was probably chosen arbitrarily as an otherwise unused character in C syntax. # would have worked just as well, I presume.
If there wasn't a character denoting it, then there would probably be trouble differentiating between code intended for the preprocessor -- how would you tell whether if (FOO) was meant to be preprocessed or not?
Because # is the standard prefix for introducing preprocessor statements.
In early C compilers, the pre-processor was a separate program which would handle all the preprocessor statements (similar to the way early C++ "compilers" such as cfront generated C code) and generate C code for the compiler (it may still be a separate program but it may also be just a phase of the compiler nowadays).
The # symbol is just a useful character that can be recognised by the preprocessor and acted upon, such as:
#include <stdio.h>
#if 0
#endif
#pragma treat_warnings_as_errors
#define USE_BUGGY_CODE
and so on.
Preprocessor directives are lines included in the code of our programs that are not program statements but directives for the preprocessor. These lines are always preceded by a hash sign (#). The preprocessor is executed before the actual compilation of code begins, therefore the preprocessor digests all these directives before any code is generated by the statements.
Source: http://www.cplusplus.com/doc/tutorial/preprocessor/
It's because # is an indicator that its a preprocessor statement
meaning before it compiles your code, it is going to include the file stdio.h
# is a pre-processor directive. The preprocessor handles directives for source file inclusion (#include), macro definitions (#define), and conditional inclusion (#if).
When the pre-processor encounters this, it will include the headers, expand the macros and proceeds towards compilation. It can be used for other purposes like halting compilation using the #error directive. This is called conditional compilation.
We know, without preprocessor programm do not run. And preprocessor is # or #include or #define or other. So # is required before #include .