Confusion between header file macro declaration and pre-processor macro declaration - c

I am new to C, so please help me with an answer before downvoting, it will help me a lot.
The definition of header file states that-
A header file consists of C function declaration and macro definitions to be shared between different files.
And the definition of C Preprocessor states that-
The C preprocessor is a macro preprocessor that transforms your program before it is compiled.All preprocessor directives begin with the # symbol.
My question is the macro declaration are done using # symbol in a program, does it depend on inclusion or exclusion of any header file, also how to find whether a particular file has a pre-defined macro declaration in it.
For example-
Say a file 'ani.h' has a macro declaration,
#define anii 2
So, once I include this file, I am allowed to use the CNAME i.e. aniidirectly?

It is easier if you look at this form the view of what the pre-processor actually does.
It reads a file and replaces text and then output a new file. The new file is sent to the compiler. The pre-proc knows nothing about C code, its just a text manipulation engine
#include xxxx
says, 'replace this line by the contents of that file'
#define FOO BAR
says, 'whenever you see FOO replace it by BAR
There are also some simple conditionals: #if etc
A macro is simply a FOO BAR replacement, usually FOO is small and BAR is large.

Although they can be used to do some nice metaprogramming tricks as well as conditional programming, macros most basic use is to make programmers lives easier via syntactic sugaring. Before compiling your code, the preprocessor module will substitute all the macros by the terms they represent, so everything you define must have been declared somewhere above the point where the macro is first used. So if you do:
#include <stdio.h>
#include <math.h>
#define MY_MACRO(x) for(int i=0; i<(x); ++i) printf("%d\n", func((x),i);
int func(int n, int m) {return pow(n, m);}
int main()
{
int a = 10;
MY_MACRO(a)
return 0;
}
The preprocessor will substitute all occurrences of MY_MACRO in your code by the loop that was defined after it. The code will then be sent to compilation. When the compiler reaches the line where the macro is used, it is necessary that printf and func are declared somewhere above this line, just as if you were writing the code without the macro. (Note that printf and pow are declared in the headers included before the definition and func is declared after the definition, but them three are declared before the first use of the macro.)
In what concerns to knowing which macros are declared inside some lib and which aren't, I believe the only way is to check the header files you are using or to read their documentation. But if you know that some specific macro may or may not be declared, you can test it using the code below:
#ifdef SOME_MACRO
printf("SOME_MACRO defined!\n");
#else
printf("SOME_MACRO not defined!\n");
#endif

Related

What happens when preprocessor lines are processed by the preprocessor? - the '.i' file

I am using Gnu cc compiler of Gcc to compile my C programs. Consider a program,
#include <stdio.h>
int main(){
return 0;
}
Now, when I pre-process the above code, using
cpp sample.c > sample.i
I get a lot of contents in sample.i which I haven't included. Say, 'stdio.h' file is preprocessed. If that is the case,
Question 1:
Why are there so many lines in my preprocessed file? I haven't used any of the standard library functions nor Macros.
Question 2:
Can anyone explain what exactly happens when the preprocessor proccess the C file.(The contents that I got in my '*.i' file)
Compiler: gcc
OS: Ubuntu
Thanks
Why are there so many lines in my preprocessed file? I haven't used any of the standard library functions nor Macros.
Preprocessing is just one part of the compilation process. It's more or less a simple textual replacement and nothing more complex is involved at the preprocessing stage. The preprocessor does not know or care whether you have used any standard functions in your code program or not. An optimizer (as part of the compilation process) might
"remove" parts that are not needed. But the preprocessor doesn't do that.
It'll do preprocessing of all the header files you have included and other header files included via your header files and so on.
Can anyone explain what exactly happens when the preprocessor process the C file.(The contents that I got in my '*.i' file)
The preprocessing involves quite a few tasks: macro replacement, conditional compilation, stringification, string concatenation etc.
You can read more about cpp in detail here: https://gcc.gnu.org/onlinedocs/cpp/
the preprocessor command #include "aFile.h" will put the hole content from aFile.h into your cpp file. And that exactly to the place, where the preprocessor directives stands. That is the reason why you can use the in aFile.h defined functions.
if you are interest to learn more about the preprocessor, there is a very good (and short) guidance on cplusplus.com
The preprocessor does text substitution. The net effect of #include <stdio.h> is to replace the #include <stdio.h> line with the contents of <stdio.h>.
Practically, <stdio.h> contains several declarations of various functions (e.g. fprintf(), fscanf()), declarations of variables (e.g. stdout, stdin), and some macro definitions (which, when used in later code, cause text substitution).
The preprocessor is specified as a phase of compilation, which takes source code as input, substitutes text as required (e.g. the #include as I have described, macro expansions, etc), and outputs the resultant source code. That output is what you are directing into sample.i
The output of the preprocessor is then input to a later phase of compilation, which actually understands declarations, definitions, statements, etc.
The phases of compilation are sequential - they occur one after the other, not all at once. So the later phase of compilation feeds no information whatsoever back to the preprocessor. It is the later phase of compilation that detects if declarations etc are used. But, since it cannot feed such information back to the preprocessor (and the preprocessor is an ignorant program that couldn't use such information anyway) the preprocessor cannot know that declarations are unused, and filter them out.
1) You may not use them, but you have included them in line 1
#include <stdio.h>
That's where what you see come from. Try to remove it to see the difference.
2) The preprocessor read your C file and processed all preprocessor directives that you have declared. All Preprocessor directives start with a '#' symbol. The '#include' will replace this line by the content of the given file. You also have the classical '#ifndef' and '#define' directive. The latter is equal to 'if' statement which allow you to activate a part of a code only if a symbol is defined
#ifndef _SOME_SYMBOL_
#define _SOME_SYMBOL_
#ifndef WIN32
#include <some_file.h>
#else
#include <some_other_file.h>
#endif
int main() { return 0;}
#endif //endof _SOME_SYMBOL_
#ifndef _SOME_SYMBOL_
#define _SOME_SYMBOL_
// this second function is ignored
int main() { return 0;}
#endif //endof _SOME_SYMBOL_
When the preprocessor reads the above file, the symbol "_SOME_SYMBOL_" is unknown, so the preprocessor initializes it. Next it includes the file whether or not it knows of WIN32. Usually this kind of symbol is passed trough command line. So part of your code is dynamically activated or deactivated.
The preprocessor will output this
void some_other_function_from_some_other_file(){}
int main() { return 0;}

How to understand a #include inside a enum definition?

How do I interpret this C code:
typedef enum {
#include <test.h>
enum1,
enum2,
…
} test_enum;
test.h includes many macros. How to understand this?
Does means that the definitions of the enum needs the macros defined inside the header file?
Can #include appear anywhere?
An #include statement may appear on any line. It is most often used to include entire declarations. However, it can be used to insert any text.
It may be that test.h contains a list of names to be declared inside the enum. It may also contain preprocessor statements, such as macro definitions or #if … #endif statements.
You would have to show the contents of test.h for further help understanding it.
#include and #define are pre processor directives not actual code.
You can put them anywhere (except as part of a literal string) - some compilers are more fussy than others (i.e. the # has to be in column 0).
The Preprocessor expands these out as required, and that is what the compiler sees. As to what it means in your case, depends on the content of test.h
There is normally a compiler option to see your code with all the preprocessor stuff expanded (used to be -e or -E on gcc I think)
The #include directive causes the contents of the included file to be placed exactly at the point of the #include directive. The resulting code is what it is once that expansion has taken place, and can be any valid language construct.
If the included file contains:
enum_a,
enum_b,
enum_c,
Then after inclusion, your code would look like:
typedef enum {
enum_a,
enum_b,
enum_c,
enum1,
enum2,
…
} test_enum;
Which is a valid construct.
A #include directive can appear anywhere. See this.
Pre-processor statements can occur anywhere and are simple textual substitutions. Whether or not the processed code is valid C code is checked by the compiler, not the pre-processor.
Depending on your compiler you can review the changes done by the pre-processor.
For gcc, this would be the -E flag, so by compiling your source code with
gcc -E in.c
you can see which changes code is contained in the enum declaration after inserting test.h and
processing it.

Preferred order of declarations and #defines in a header file

I am programing in C language in Linux platform . I want to know should be the order of declarations and #defines in a header file.
For example if my header file includes following thing can anyone please suggest me what should the perfect order to arrange all these declarations, function like macros , exteren declarations, etc.
This can be really beneficial for arranging all these things in a header file properly in terms of readability and coding standards.
Below is the sample header file (I want to arrange the following in a proper order) :
#include <pthread.h> // Including Header files
#include <signal.h>
#define IMAGE_DIRECTORY "Abcdefgh..." // Providing #defines
#define FAILED_TO_RECOGNIZE "Xykbkksk..."
#define PROGRESS_FRAME_COLOR "#8e8ea1"
#define FRAME_BG_COLOR "#7c90ac"
#define PRINT_FUNCTION_NAME fprintf(stderr,
"CTRL IN FUNCTION : %s\n",__func__); // Macro like functions
typedef struct {
int userId; // Structure
char name[32], rollNo[32];
char class[16], section[16];
unsigned long Id;
}data_type;
int noOfUsersList=0, usersListCount=0; // Global variables
I haven't done this for years but when I was heavily developing for Unix, MS.DOS, OS/2, NetWare, and Windows simultaneously I developed this practice:
Language #includes
Operating system #includes
#includes from other subsystems, e.g. X11.
My own application #includes.
My own local #defines for this source file.
My own forward declarations for this file.
Maybe you can reverse (1) and (2) but I found this order to work the best across quite a number of compilers and operating systems.
Coding style is subjective, personally I use the rules and methods described below, but please note that are my own opinions and no absolute truths. Yet they are based on long experience and in some cases on widely-recognized coding standards (MISRA, CERT etc).
Rules:
C programming is done in "code modules", where every module consists of a .h file and a .c file.
#includes shall always be in the .h file and never in the .h file, since the .h file should be regarded as public. You want the person that is going to use your module to know what dependencies there are.
There is never a reason to use non-const global variables in C, so where to place non-const globals and externs isn't relevant to me.
.h files shouldn't contain any definitions. This is not only bad program design, it is also an excellent way to conjure numerous hard-to-solve linker errors.
In a .h file, the following items are allowed to appear, in the stated order:
Start of header guard. (#ifndef MYHEADER_H ...)
Library #includes.
Other #includes.
Impl.-specific compiler settings such as compiler options set with #pragmas.
Public numeric constants as #defines.
Public macros.
Public type definitions, including opaque types.
Declaration of public constants (declared as extern const).
Inline function definitions (rare special case, avoid if possible).
Function prototypes.
End of header guard. #endif
In a .c file, the following items are allowed to appear, in the stated order:
Include of its own corresponding .h file.
Private numeric constants in #defines.
Private macros.
Definition of opaque types, that were declared as incomplete type in the corresponding .h file.
Private type definitions.
Definition of public constants (declared as extern const in the .h file).
Definition of private constants (static const).
Definition of private variables at file scope (static).
Declaration of private functions (declared as static type func (type param);)
Definition of the public functions declared in the .h file.
Definition of private functions.
Macro definitions with #define are not declarations. The only requirement is that macros should be defined before their usage. They stay defined until end of compilation unit, or an explicit #undef (or a redefinition...).
My stylistic convention is to define statement-like macros as having a "function" like syntax, something like:
#define PRINT_FUNCTION_NAME() fprintf(stderr, \
"CTRL IN FUNCTION: %s #%s:%d\n", __func__, __FILE__, __LINE__)
Notice the empty formal macro argument (ie first ()) and the lack of terminating semicolon (because you will use it as a quasi-function call, e.g. PRINT_FUNCTION_NAME(); statement). Notice also use of __FILE__ and __LINE__ in a debug message.
Quite often, a statement-like macro is a do{ something } while(0) because this is a syntax which has a statement like look and can always be used as a statement (including as the then part of an if, or in else branch, etc...). An example from <ncurses.h> :
#define getsyx(y,x) do { if (newscr) { \
if (is_leaveok(newscr)) \
(y) = (x) = -1; \
else \
getyx(newscr,(y), (x)); \
} \
} while(0)

Why does my #define macro appear to be a global?

I was investigating a compile and link issue within my program when I came across the following macro that was defined in a header and source file:
/* file_A.c */
#ifndef _NVSize
#define _NVSize 1
#endif
/* file_B.c */
#include "My_Header.h"
#ifndef _NVSize
#define _NVSize 1
#endif
/* My_Header.h */
#define _NVSize 1024
Nothing out of the ordinary yet, until I saw the following information in the GCC output map file:
/* My Map File */
...
.rodata 0x08015694 _NVSize
...
My understanding of the map file is that if you see a symbol in the .rodata section of the map file, this symbol is being treated as a global variable by the compiler. But, this shouldn't be the case because macros should be handled by the preprocessor before the compiler even parses the file. This macro should be replaced with it's defined value before compiling.
Is this the standard way that GCC handles macros or is there some implementation specific reason that GCC would treat this as a global (debug setting maybe)? Also, what does this mean if my macro gets redefined in a different source file? Did I just redefine it for a single source file or did I modify a global variable, thereby changing _NVSize everywhere it's used within my program?
I think the compiler is free to assign your macro to a global variable as long as it ensures that this produces the exact same result as if it did a textual replacement.
During the compilation the compiler can mark this global specially to denote that it is a macro constant value, so no re-assignment is possible, no address can be taken, etc.
If you redefine the macro in your sorce, the compiler might not perform this transformation (and treat it as you'd expect: a pre-compier textual replacement), perform it on one of the different values (or on all of them say, using different names for each occurrance), or do domething else :)
Macros are substituted in the preprocessor step, the compiler only sees the substituted result. Thus if it sees the macro name, then my bet is that the macro wasn't defined at the point of usage. It is defined between the specific #define _NVSize and an #undef _NVSize. Redefining an existing macro without using an #undef first should result in a preprocessor error, AFAIR.
BTW, you shouldn't start your macro names with an underscore. These are reserved for the implementation.

C function seemingly not defined anywhere!

I'm looking at the vim source code, specifically the file normal.c, and I see this function nv_operator being used, but it's not defined anywhere (I grepped the entire src directory)
It's only declared as:
static void nv_operator __ARGS((cmdarg_T *cap));
I've looked up the definition of __ARGS but it's just ... nothing (pretty much)
in vim.h:
#define __ARGS(x) x
So what could be going on? Is this some kind of C technique to create a dummy function or something?
There is a definition present here:
/*
* Handle an operator command.
* The actual work is done by do_pending_operator().
*/
static void
nv_operator(cap)
cmdarg_T *cap;
....
That style of definition is using an identifier list for its parameters. The style is deprecated (obsolescent) but can still be used in C. The identifiers are named in the parameter list, and their type are named in declarations that immediately follow the function declarator but precede the functions body.
The __ARGS macro is there to handle compilers that don't know about prototypes for functions (the other form to declare parameters - with type and name combined directly in the function parameter list). It would then just emit no parameters at all in declarations, i think.
Update: See this code in vim.h:
#if defined(MACOS) && (defined(__MRC__) || defined(__SC__))
/* Apple's Compilers support prototypes */
# define __ARGS(x) x
#endif
#ifndef __ARGS
# if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264)
# define __ARGS(x) x
# else
# define __ARGS(x) ()
# endif
#endif
It's simply a forward declaration, so that the function is known to the C compiler (and can be used (called from other functions)) before it's actually defined (in line 8247). The actual formatting of the definition (which includes newlines) makes it hard to grep for it's existence.
Don't get distracted by the __ARGS macro. It's only a compatibility macro for the different function declaration syntaxes of K&R C vs. ANSI C.
In ANSI C a function declaration must look like this:
int getopt(int, char * const *, const char *);
In the (older) Kernighan and Ritchie C http://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
int getopt();
Its hard to find because of how it is defined:
nv_operator(cap)
appears on a line by itself.
I am not too sure what is going on, but here are some hints to help you in your search:
First of all, the __ARGS macro seems to be there because there may be versions of C where you shouldn't include the args in the declaration of the functions (Notice that the macro is defined differently depending on other preprocessor symbols... the comments say it).
Secondly, searching for the function nv_operator may not be good enough. The function might be generated by macros and such, so you can't search for an explicit definition.... for example, maybe the "nv" prefix is added by the preprocessor.
Hope this helps.

Resources