Does the use #ifndef and #define change the memory allocation? - c

I recently saw a header file with such defines:
#ifndef DEFINE_ME
#define DEFINE_ME 1
char abc[10];
#endif
but I also found that DEFINE_ME was never defined in any other header file of the project so why was #ifndef used? does it have to do any thing with memory?

It's called an include guard.
The purpose of DEFINE_ME is to prevent the particular (where it's defined) header file being included multiple times accidentally.
To understand how it works, try without include guard:
header.h:
int x = 5;
file.c:
#include "header.h"
#include "header.h"
int main() {
printf("%d\n", x);
}
and then try with an include guard:
header.h:
#ifndef DEFINE_ME
#define DEFINE_ME 1
int x = 5;
#endif
file.c:
#include "header.h"
#include "header.h"
int main() {
printf("%d\n", x);
}
When you have DEFINE_ME, the header will be included the first time in fil.c, the header.h is included as DEFINE_ME wasn't defined before. But the next #include "header.h" wouldn't include the contents of the guard as DEFINE_ME has already been defined by the previous inclusion.

It's include guard.
The purpose of This is to prevent multiple declaration of variable.
ifndef = if not defined.
then define it..
if defined then use the previous declaration ..
suppose u have two header files
header1:
#ifndef DEFINE_ME
#define DEFINE_ME 1
#endif
header 2:
#ifndef DEFINE_ME
#define DEFINE_ME 1
#endif
now if in c file header 2 is included first then it will include the value from header 2 not from header 1.. as it is already defined in header 2
You can have header file guard also as explained below:
Header1.h
#ifndef _header1
#define _header1
#ifndef VAR1
#ifdef VAR1 5
#endif
#endif
Header2.h
#ifndef _header2
#define _header2
#ifndef VAR1
#ifdef VAR1 5
#endif
#endif
Now you have used a guard so that u by mistake include same header in different files of same project then also u will be safe.

Related

How can I avoid redefinition of types while including multiple header files?

I'm working on recompiling a C project and I'm not sure how do I fix this problem in a right way.
Here is a situation -
a.h
#ifndef A_H
#define A_H
typedef int INT;
// other variables and function definition
#endif
b.h
#ifndef B_H
#define B_H
typedef int INT;
// other variables and function definition
#endif
main.c
#include "a.h"
#include "b.h"
int main()
{
INT i = 10;
return 0;
}
The error I get in Linux with gcc:
In file included from ./main.c,
./b.h:<linenumber>: error: redefinition of typedef ‘INT’
a.h.h:<linenumber>: note: previous declaration of ‘INT’ was here
I have to include both headers due to other variables and functions. I haven't written this code, but this seems to compile in my Solaris environment which is strange. What can I do to fix this ?
Probably the native compiler on Solaris accepts that you can redefine a typedef (probably provided that the new typedef is identical to the previous one which is the case here).
I'd introduce another header file mytypes.h like this:
mytypes.h
#ifndef MYTYPES_H
#define MYTYPES_H
typedef int INT;
#endif
Include mtypes.h whereever INT is used, possibly even in main.c:
a.h
#ifndef A_H
#define A_H
#include "mytypes.h" // can be removed if INT is not used in a.h
// other variables and function definition
#endif
b.h
#ifndef B_H
#define B_H
#include "mytypes.h" // can be removed if INT is not used in b.h
// other variables and function definition
#endif
main.c
#include "a.h"
#include "b.h"
#include "mytypes.h" // not really necessary because it's already included
// via a.h and b.h, but still good practice
int main()
{
INT i = 10;
return 0;
}
If you are allowed to change the library code or compiler options then Michael Walz's answer is the way to go
In the unfortunate case that it's not changeable then it can be worked around by renaming before including the header then undefine it
#define INT INT_A
#include "a.h"
#undef INT
#define INT INT_B
#include "b.h"
#undef INT
Now just use INT_A for all the interfaces in a.h instead of INT. Same to INT_B in b.h

C preprocessor #error in header file included in multiple source files

I have two source files, main.c and datamgr.c - and two header files, config.h and datamgr.h
The testing system we're using expects these files, and only these files.
main.c:
#include "datamgr.h"
#include "config.h"
int main() {
custom_type a = 1;
a = foo();
return 0;
}
datamgr.c:
#include "datamgr.h"
#include "config.h"
custom_type foo() {
custom_type a = 1;
return a;
}
datamgr.h:
#ifndef DATAMGR_H
#define DATAMGR_H
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
custom_type foo();
#endif
config.h:
#ifndef CONFIG_H
#define CONFIG_H
#ifndef SET_MAX_TEMP
#error "Max temperature not set."
#endif
#ifndef SET_MIN_TEMP
#error "Max temperature not set."
#endif
typedef custom_type uint16_t
#endif
Now, the problem is that I can only define SET_MAX_TEMP and SET_MIN_TEMP in main.c, but both main.c and datamgr.c need both the header files. So if I leave them undefined in datamgr.c I get a compiler error. However, if I do define them in datamgr.c and later overwrite them in main.c, I get a different compiler error.
Please, any assistance as to how to get this horrible setup to work would be greatly appreciated.
You can pass these defines directly while compiling:
gcc -DSET_MAX_TEMP -DSET_MIN_TEMP <your files>
In datamgr.c do:
#define SET_MAX_TEMP
#define SET_MIN_TEMP
#include "datamgr.h"
#include "config.h"
#undef SET_MAX_TEMP
#undef SET_MIN_TEMP
In a comment, you said:
Because main.c is the file that our testing system uses to implement the test scenarios.
In that case, make sure that the testing system defines those macros in the command line of the compiler for every file being compiled.

Multiple inclusion of header file error in C

So I have a header file let's say "header.h" which is protected as follows:
#ifndef __HEADER1_H
#define __HEADER1_H
//type and function def
typedef struct
{
float r; //process noise
float k; //process gain
}state_t;
int get_state(state_t* state, float b);
#endif
Now I have two other headers which I defined as follows:
#ifdef __HEADER2_H
#include "header.h"
//function def
#endif
Second header:
#ifdef __HEADER3_H
//function
//the reason it is done this way is for cnditional compiling such that if the caller
//defines __HEADER3_H t this file won't be included.
#include "header.h"
#endif
Now as I suspected the compiler complained that types and functions defined in header.h were not detected in the source implementation of header2 and header3. So I included header.h in the source files as well. Now the linker is complaining functions that are defined in header.h are multiply defined.
My understanding was since the header.h is protected by ifndef it will only be included once so I don't see the problem.
here is the error that I am getting:
Symbol get_state multiply defined(by kalman.o and dsp.o)
Is there any chance that I am doing something unusally wrong?
#ifndef __HEADER1_H
#define __HEADER_H
The problem is your guard (__HEADER_H) is different from what you are checking for (__HEADER1_H). Make these both the same value.
The typical "guard" for a header file is:
myheader.h:
#ifndef _MYHEADER
#define _MYHEADER
<do stuff>
#endif
Optionally where myheader.h is included, you can do:
#ifndef _MYHEADER
#include "myheader.h"
#endif
This is optional and basically is only to improve compile performance.

How can I stop #including redundant headers when I use header files like these?

So I'm still getting used to modular programming, and want to make sure I'm adhering to best practices. If I have the two module header files below, will the the headers #included by each file (for example "mpi.h") be included multiple times? Is there a proper way to account for this?
Also, my module headers typically look like these examples, so any other criticism/pointers would be helpful.
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdlib.h>
#include "mpi.h"
void foo();
#endif
and
/* bar.h */
#ifndef BAR_H
#define BAR_H
#include <stdlib.h>
#include "mpi.h"
void bar();
#endif
And use the sample program:
/* ExampleClient.c */
#include <stdlib.h>
#include <stdio.h>
#include "mpi.h"
#include "foo.h"
#include "bar.h"
void main(int argc, char *argv[]) {
foo();
MPI_Func();
bar();
exit(0)
}
What do you mean by 'include'? The preprocessor statement #include file copies the contents of file and replaces the statement with these contents. This happens no matter
If by 'include' you mean "the statements and symbols in these files will be parsed multiple times causing warnings and errors", then no, the include guards will prevent that.
If by 'include' you mean "some part of compiler will read some part of these files", then yes, they'll be included multiple times. The preprocessor will read the second inclusion of the file and replace it with a blank line because of the include guards, which incurs a tiny overhead (the file is already in memory). Modern compilers (GCC, not sure about others) will probably be optimized to avoid this, however, and note that the file has include guards on the first pass and simply discard future inclusions, removing the overhead - Don't worry about speed here, clarity and modularity are more important. Compilation is a time-consuming process, for sure, but #include is the least of your worries.
To better understand include guards, consider the following code sample:
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
// Define to 1 in first block
#define GUARDED 1
#endif
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
// Redefine to 2 in second block
#define GUARDED 2
#endif
After (the first pass of) preprocessing, what will GUARDED be defined to? The preprocessor statement #ifndef or its equivalent, #if !defined() will return false if their argument is indeed defined. Therefore, we can conclude that the second #ifndef will return false, so only the first definition of GUARDED will remain after the first pass of the preprocessor. Any instance of GUARDED remaining in the program will be replaced by 1 on the next pass.
In your example, you've got something slightly (but not much) more complicated. Expanding all the #include statements in ExampleClient.c will result in the following source: (Note: I indented it, but that's not normal style for headers and the preprocessor won't do it. I just wanted to make it more readable)
/* ExampleClient.c */
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include <stdio.h>
#ifndef STDLIB_H
#define STDLIB_H
#define NULL 0 //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
//#include "foo.h"
#ifndef FOO_H
#define FOO_H
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
void foo(void);
#endif
//#include "bar.h"
#ifndef BAR_H
#define BAR_H
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
void bar(void);
#endif
void main(int argc, char *argv[]) {
foo();
MPI_Func();
bar();
exit(0); // Added missing semicolon
}
Go through that code and note when various definitions are performed. The result is:
#define STDLIB_H
int abs (int number); //etc.
#define STDLIB_H
#define NULL 0 //etc.
#define MPI_H
void MPI_Func(void);
#define FOO_H
void foo(void);
#define BAR_H
void bar(void);
With respect to your request for other criticism/pointers, why are you #including stdlib.h and mpi.h in all your headers? I understand that this is a stripped down example, but in general, header files should only include files necessary for the declaration of their contents. If you use a function from stdlib or call MPI_func() in foo.c or bar.c, but the function declarations are simply void foo(void), you shouldn't include these files in the header function. For example, consider the following module:
foo.h:
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c:
#include <stdlib.h> // Defines type size_t
#include "mpi.h" // Declares function MPI_func()
#include "foo.h" // Include self so type definitions and function declarations
// in foo.h are available to all functions in foo.c
void foo(void);
size_t length;
char msg[] = "Message";
MPI_func(msg, length);
}
In this example, the implementation of foo() requires stuff from stdlib and mpi, but the definition does not. If foo() returned or required a size_t value (typedef'ed in stdlib), you'd need to #include stdlib in the .h file.
Mostly no, with a bit 'yes'. Your header files will be 'read' more than once but at second and later time the preprocessor will cut off all the contents. This implies that it won't waste your compiler's time and also #includes inside your #ifdef blocks will be done only once (per header file).
It's a good practice. Myself, I also add the following line before #ifdefs:
#pragma once
When supported by the particular compiler, it guarantees that the file will actually be read only once. I think it's a little bit more optimal that way.
So, to sum up:
header guards like you are using prevent compiler from interpreting the header contents more than once but possibly can cause the preprocessor to parse it more than once (which is not a big problem),
#pragma once causes the particular header file to be read only once.
When using both, #pragma once should be in effect if supported by compiler; if not, header guards will apply.
1) GOOD: you have an "include guard". "stdlib.h", "mpi.h" and "void foo()" are only seen by the compiler the first time you #include "foo.h"
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdlib.h>
#include "mpi.h"
void foo();
#endif
2) BAD: This will #include the entire contents of "foo.h" every time you use it:
/* foo.h */
#include <stdlib.h>
#include "mpi.h"
void foo();
3) By #include", I mean "once per compilation unit" (i.e. the same .c source file).
This mainly "protects" against a header (foo.h) calling another header ("bar.h) which might recursively call the first header.
Every different compilation unit that #includes foo.h will always get "stdlib.h", "mpi.h" and "void foo()". The point is that they'll be seen only once - not multiple times in the same compilation unit.
4) This is all "compile-time". It has nothing to do with libraries (which are "link time").
Yes, mpi.h will be included multiple times (as will stdlib.h); if mpi.h has include guards similar to foo.h and bar.h, then it won't be an issue.

Possible to #if or #ifdef based on preprocessor-generated "thing"

I'm trying to engage in some C-preprocessor-only templating efforts in order to type-specialize some code. I've tried to boil it down a bit, so this example seems trivial and pointless, but the real challenge is getting the "include" blocking.
Say I have a "template" file, that gets #included from other source files that define T_ELEMENT_TYPE before including the template.
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)
#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)
int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
// do something with arg
return 0;
}
#endif // Guard #ifdef
Then I want to include that template from multiple instantiation sites, but I only want the templated function to be generated ONCE per unique T_ELEMENT_TYPE (so as not to create duplicate symbols.) Like, say this:
// Template-using file...
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE float
#include "Template.c"
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE
int someOtherFunc()
{
int foo = 42;
foo = SymbolForint(foo);
float bar = 42.0;
bar = SymbolForfloat(bar);
return foo;
}
So I'm looking for something I can use in the template code. I imagined it might look something like this (although this does not work):
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)
#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)
int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
// do something with arg
return 0;
}
#endif // Guard #ifdef
This particular incantation blocks ALL multiple instantiations of the template, not just for different values of T_ELEMENT_TYPE.
Is there a trick I can use to get this effect? Or am I just off the C-Preprocessor reservation, so to speak?
I think you're off the reservation. The first "argument" to #define, the macro name, isn't subject to macro-expansion. So I don't think the preprocessor can define a different symbol according to the value of T_ELEMENT_TYPE. Neither can the preprocessor construct a "list" of already-seen types and check for existence in that.
So I think the include-guard will have to be outside the file:
#ifndef included_mytemplatefile_h_int
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE int
#include "mytemplatefile.h"
#define included_mytemplatefile_h_int
#endif
Alternatively, if your template file header only declares the function SymbolFor_int, instead of defining it, then multiple inclusion isn't harmful. You could have a normal include guard around the parts of the file that don't depend on the current value of T_ELEMENT_TYPE, including the definitions of PASTER, EVALUATOR, SYMBOLNAME. You'd need a separate template file containing definitions, which the program (rather than each translation unit) needs to have exactly once:
template_%.c :
echo "#define T_ELEMENT_TYPE $*" > $#
echo "#include \"mytemplatedefinitions.c\"" >> $#
Then add template_int.o to the list of files linked into your program.

Resources