Can i write preprocessor directives anywhere in my c program? - c

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.

Related

C: Are #define directives global?

I'm somewhat confused by #define statements. In libraries, they seem to be a means of communication across different files, with lots of #ifdefs and #ifndefs.
Having said that, I now have two files file1.c and file2.c compiled together, with #define TEST 10 inside file2.c. Yet, when I use TEST inside file2.c the compiler gives the following error message:
'TEST' undeclared (first use in this function)
Are #define directives global?
#defines are not global, they are just a substitution where ever they are used (if declared in the same compile unit)
They are not globals, they are not symbols, they are irrelevant at linkage, they are only relevant at pre-compilation.
#defined macros are global in that they do not follow normal C scoping rules. The textual substitution from the macro will be applied (almost) anywhere the macro name appears after its #define. (Notable exceptions are if the macro name is part of a comment or part of a string literal.)
If you define a macro in a header file, any file that #includes that header file will inherit that macro (whether desired or not), unless the file explicitly undefines it afterward with #undef.
In your example, file2.c does not know about the TEST macro. How would it know to pick up the #define from file1.c? By magic? Since macros perform textual substitution on the source code, there is no representation of them in the generated object files. file2.c therefore needs to know that substitution rule itself, and if you want that shared across multiple files, that #define needs to live in a common header file that your .c files #include.
If you're asking specifically about how many of the #ifdefs that you see in libraries work, many of them are likely checking against pre-defined macro names provided by the compilation environment. For example, a C99 compiler defines a __STDC_VERSION__ macro that specifies the language version; a Microsoft compiler defines an _MSC_VER macro. (Often these predefined macros start with leading underscores since those names are reserved for the compiler.)
Additionally, most compilers allow defining simple macros as command-line arguments. For example, you might compile your code via gcc -DNDEBUG file1.c to compile file.c with NDEBUG defined to disable asserts.
In case somebody reads this later, and to add some practical information:
Some environments like atmel, vs, or iar, allow you to define global #define directives. They basically pass these defined values to the precompiler in some commandline format.
You can do the same in batch commands or makefiles, etc.
Arduino always adds a board variant (usually located at hardware\arduino\variants) to all compilations. At that point you can create a new board that contains your global define directives, and use it that way. For example, you can define a mega2560(debug) board out of the original mega2560 that contains some debug directives. You will add a reference to that variant in "boards.txt", by copy pasting some text, and properly modifying it.
At the end of the day, you will have to give that global hfile or global directive to the compiler in one way or another.
you should make a file1.h and put your defines there. Then in file2.c
#include "file1.h"
easy as a pie :)

Setting the scope of a MACRO

I have a general doubt ..
Is there a way we limit the scope of a MACRO within a .C file just like a static function ?
Macros are done by the pre-processor.
The pre-processor reads all files being processed and applies macros and macro logic, the results of which are then passed to the compiler.
Once a macro is defined, its value will be used everywhere the macro is referenced, even in other files.
Please see the GCC Documentation for details regarding macro usage.
The general practice is to #undef the macro when you're done with it. Error prone, but it works.
Macros don't have any sort of block scope.
You can place the macro in the .c file where you want it to be used instead of a header file and it won't be accessible from other files (although some compilers allow inclusion of .c files but no one does that, well no one that's sensible).
Also mentioned below is the use of #undef but that can quickly start to get messy if you use that macro a lot.
All macros are already like static functions, in that they can only be used in the translation unit in which they're defined. If you want to restrict the areas where you can use a particular macro, just define it in a sensible place.
a macro is evaluated by the preprocessor, not by the compiler.
it doesn't know anything about compilation units, so you cannot restrict it's use to one.
instead it is evaluated within the translation unit.
the macros life cycle starts in the line it is defined (all lines above it do know nothing about the macro), and it ends either at the end of the translation unit or whenever it get's undefined using "#undef"
All C macros are limited to the translation unit (a single C file) unless they are defined in a header and being included to every translation units.
Unfortunately, a translation unit is often big, easily hundreds to thousands of lines of code, and macros are context dependent and it would be much more useful if it can be limited to much smaller context (such as a block scope). Lacking scope limits macro usage in C, mostly global constants, a few universal simple routines, and often need all capital names or some trick to manage pollutions).
However, higher order functions can be easily achieved with macros. Think about how we use natural language, where we may use "it" to refer any thing too long to repeat within the context. A scoped macro system will enable the same ability.
I have developed MyDef, which is essentially a scoped macro system.

Preprocessor on C

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.

Why there is no semicolons after preprocessor directives?

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

Why # is required before #include<stdio.h>?

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 .

Resources