Please,
could you tell me what does the code below do?
...code...
#include file.h
...code...
I was used to put includes a the beggining of each file. I have never seen this before and also wasn't able to find anything in the internet.
#include is a pre-processor directive that takes the file given as the argument and dumps its contents in the current file. Typically, this is used to include definitions of commons functions from header files, but there's no necessity to use it in that way.
It's usage is not limited to the starting of the file, but note that the variables, macros or functions declared in this header will not be usable before the include statement even if on the same file.
As everyone tells you #include can be used every where (provided it is on its own logicial line). And there are cases where you want to #include several times the same file. Read first the X macro wikipage, and the C preprocessor wikipage.
And I have a concrete example in my MELT monitor (related to MELT ...).
I have a predef-monimelt.h (generated) file containing lines like
MOM_PREDEFINED_NAMED( name, id,hash) e.g.
MOM_PREDEFINED_NAMED(GET,_9dsak0qcy0v_1c5z9th7x3i,1573018885)
MOM_PREDEFINED_NAMED(HEAD,_47fatww79x6_vh8ap22c0ch,3922245622)
MOM_PREDEFINED_NAMED(web_handler,_7sav6zery1v_24sa6jwwu6c,2339220870)
#undef MOM_PREDEFINED_NAMED
My monimelt.h file (a real header file) define external pointers and an enum, so has notably:
// declare the predefined
#define MOM_PREDEFINED_NAMED(Name,Id,H) extern momitem_t* mom_named__##Name;
#include "predef-monimelt.h"
/// declare the hash of the predefined as an enum
#define MOM_PREDEFINED_NAMED(Name,Id,H) mom_hashname__##Name = H,
enum {
#include "predef-monimelt.h"
};
My main.c file contains notably a routine :
// if this routine is compiled, we are sure that all predefined hashes
// are unique
const momitem_t *
mom_predefined_item_of_hashcode (momhash_t h) {
switch (h) {
#define MOM_PREDEFINED_NAMED(Nam,Id,Hash) case Hash: return mom_named__##Nam;
#include "predef-monimelt.h"
default:
return NULL;
}
}
but my items.c includes the predef-monimelt.h file twice (to create the predefined items at initialization, and to define their variables):
void mom_create_predefined_items (void) {
int nbnamed = 0;
#define MOM_PREDEFINED_NAMED(Nam,Id,H) do { \
mom_named__##Nam = mom_make_item_of_identcstr(#Id); \
mom_named__##Nam->i_space = momspa_predefined; \
mom_register_item_named_cstr (mom_named__##Nam, #Nam); \
nbnamed ++; \
} while(0);
#include "predef-monimelt.h"
} // end of mom_create_predefined_items
// declare the predefined
#define MOM_PREDEFINED_NAMED(Nam,Id,H) momitem_t* mom_named__##Nam;
#include "predef-monimelt.h"
FWIW, the MELT monitor is GPLv3+ licensed software
Related
I have a macro that should be used both in my source file and header one. However I don't wan't other code linked to the final object to access that macro (more than anything else I don't want the macro to go causing unexpected errors in other files). I thought about using a macro with a long and complicated name that will be unlikely used from other code, however this solution kinda looks ugly to me. Obviously the most simple solution would be to undefine the macro in some way, however if I define the macro in the header and then undefine it – I think – I won't be able to access it anymore from the source file. What should I do?
// hi.h
#define string char *
void greet(string x);
// hi.c
#include "hi.h"
void greet(string x) {
printf("Hi!");
}
Okay, don't kill me, this was just an example, i know #define string char * is horrible.
Last minute thought: Maybe I can underfine the macro at the end of the source file, is this acceptable to do?
I guess you could conditionally "undefine" macro at the end of the header when the a magic macro is not defined. The blessed source file would have to define this macro prior to including a header.
// header.h
...
#ifndef MAGIC_MACRO
#undef string
#endif
// common source
#include "header.h"
// blessed source
#define MAGIC_MACRO
#include "header.h"
This solution will work great as long as no macro defined inside the header uses string macro.
What should I do?
Pick option 1 a macro with a long and complicated name that will be unlikely used from other code as it's the simplest and most obvious. Do not use a complicated name - just use a name so that you and other developers will know it's a private symbol, that's all.
// hi.h
// this macro is private
#define _lib_string char *
Remember about reserved words. Example: https://github.com/GNOME/glib/blob/main/glib/glib-private.h#L32 .
he most simple solution would be to undefine the macro in some way, however if I define the macro in the header and then undefine it – I think – I won't be able to access it anymore from the source file
If you go this way, you'll end up with spaghetti code, where some global state affects what you have. For example:
// hi.h
#define string char *
void greet(string x);
#ifndef FROM_HI_C
#undef string
#endif
// hi.c
#define FROM_HI_C
#include "hi.h"
void greet(string x) {
printf("Hi!");
}
Maybe I can underfine the macro at the end of the source file, is this acceptable to do?
Other files see only the header file - they are unaffected by anything in the source file.
I am unsure about where to write the declaration and the call of a macro that replaces the code with a function. I do not really know if I should write the macro to the .h or .c file.
Before reading some stuff on the best ways to create libraries, I was just putting all the code in a header file and including it on my main, i.e.
#ifndef LIB
#define LIB
#define def_func(type) \
type func(type x) \
{ \
// Do something
}
func(int)
#endif
Some other functions use these defined functions so I had to call the macro to the .h file.
Firstly, I think that a few small edits are needed in the code from the question:
#ifndef LIB
#define LIB
#define def_func(type) \
type func(type x) \
{ \
/* Do something */ \
}
def_func(int)
#endif
The question does not detail what objective is being achieved, but I would assume that the goal is to create something that behaves like a template in C++, where the code is defined in one place and instances are created for different types by using the macro def_func.
One thing to be aware of is if you are using def_func more than once in your project, then you are going to have linker errors due to the same global symbol being used in multiple places, even if def_func is used in separate files. This could be avoided by making the function static if def_func is used multiple times but never more than once in the same file. Although, this would restrict the function from being called from multiple files.
Global symbol redefinition could also be avoided by adding another argument to the #define as follows:
#define def_func(func, type) \
type func(type x) \
{ \
/* Do something */ \
}
This would allow the function identifier to be specified uniquely. For example:
def_func(func_int, int)
would expand to:
int func_int(int x)
{
/* Do something */
}
This way a unique identifier would be created for each instance.
The #define should be placed in the header file if you intend to use the macro from multiple C source files. The macro should be used within C source files only, since using this in the header file would instantiate an object with the same global symbol in each case the header file is included. Although, this would be allowable if the functions are defined as static.
Lastly, if you plan to call the function created from multiple locations, you will need a macro that can be used in a header file associated with the module defining the function to prototype the function. For example:
#define def_func_proto(func, type) \
type func(type x)
So to sum it up, your library .h file would contain:
#define def_func(func, type) \
type func(type x) \
{ \
/* Do something */ \
}
#define def_func_proto(func, type) \
type func(type x)
Then using the integer case as an example, the C source file may include:
def_func(func_int, int)
Which would expand to (note that the actual expansion will not have line breaks):
int func_int(int x)
{
/* Do something */
}
In this case, the header file may contain:
def_func_proto(func_int, int);
Which would expand to:
int func_int(int x);
Finally, I would note that am not certain that this is a good programming practice, in general. You will want to be very cautious in implementing this in your program.
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.
Alongside main.c file, I have following my_custom_data_structure.c file in my project. My my_custom_data_structure.c file contains a lot of variables, functions, etc.
I am using #include "my_custom_data_structure.c" directive in main.c.
Problem
I would like to import only single function called foo from my_custom_data_structure.c. I don't need all the variables and functions, which are declared in my_custom_data_structure.c file.
Any insights appreciated.
File structure
-
|- main.c
|- my_custom_data_structure.c
Content of my_custom_data_structure.c
#include <stdio.h>
int DELAY = 20;
int SPEED = 7;
char GRANULARITY_CHAR = 'g';
unsigned int RANGE = 3;
void foo(){
// TODO: In future, this function will print SPEED.
printf("foo works!");
}
/*
The rest of this file is filled by a lot
of code, which is not needed for main.c
*/
Content of main.c
#include <stdio.h>
#include "my_custom_data_structure.c"
int DELAY = 3;
int main(){
foo();
printf("Delay is %d", DELAY);
return 0;
}
UPDATED: Added working example
The usual way is to compile them separately. So you have your main.c, and your extra.c, and you should create a extra.h (and include it in main.c).
In this extra.h, put in declarations for anything that is to be exported from your extra.c file.
For example any functions that should be available to other files. All other functions should be declared/defined only in your extra.c as static, so that they are not available as symbols to be linked when main.c is compiled.
Normally, you don't include source files (.c) inside other source files (or inside headers). It's possible (and occasionally necessary), but it isn't usual.
Unless you've designed the my_custom_data_structure.c to allow you to specify which functions are to be compiled, you get everything in the file. For example, you could use:
#ifdef USE_FUNCTION1
void function1(void *, …)
{
…
}
#endif /* USE_FUNCTION1 */
around each function, and then arrange to
#define USE_FUNCTION1
before including the source, but that's not usually a good way of working. It's fiddly. You have to know which functions you use, and which other functions those need, and so on, and it is vulnerable to changes making the lists of USE_FUNCTIONn defines inaccurate. Of course, the source code might have blocks of code like:
#ifdef USE_FUNCTION1
#define USE_FUNCTION37
#define USE_FUNCTION92
#define USE_FUNCTION102
#endif /* USE_FUNCTION1 */
so that if you say you use function1(), it automatically compiles the other functions that are required, but maintaining those lists of definitions is fiddly too, even when the definitions are USE_MEANINGFUL_NAME instead of a number.
Create a header (my_customer_data_structure.h) declaring the functions and any types needed, and split the implementation into many files (mcds_part1.c, mcds_part2.c, …).
Compile the separate implementation files into a library (e.g. libmcds.a), and then link your program with the library. If it's a static library, only those functions that are used, directly or indirectly, will be included in the executable.
Let's say I have a header file "header.h" with a function definition.
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
This header file has an include guard. However, I'm kind of confused as to what #define HEADER_FILE is actually doing. Let's say I were to forget the include guard, it would have been perfectly legal for me to completely ignore adding '#define HEADER_FILE'.
What exactly are we doing when we define HEADER_FILE? What are we defining? And why is it okay to forget the include guard in which case we can also forgot adding #define HEADER_FILE?
It's a preprocessor macro.
All of it is preprocessor syntax, that basically says, if this macro has not already been defined, define it and include all code between the #ifndef and #endif
What it accomplishes is preventing the inclusion of file more than once, which can lead to problems in your code.
Your question:
And why is it okay to forget the include guard in which case we can also forgot adding #define HEADER_FILE?
It's OK to forget it because it's still legal C code without it. The preprocessor processes your file before it's compiled and includes the specified code in your final program if there's no logic specifying why it shouldn't. It's simply a common practice, but it's not required.
A simple example might help illustrate how this works:
Your header file, header_file.h we'll say, contains this:
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
In another file (foo.c), you might have:
#include "header_file.h"
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
What this will translate to once it's "preprocessed" and ready for compilation is this:
int two(void){
return 2;
}
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
All the include guard is accomplishing here is determining whether or not the header contents between the #ifndef ... and #endif should be pasted in place of the original #include.
However, since that function is not declared extern or static, and is actually implemented in a header file, you'd have a problem if you tried to use it in another source file, since the function definition would not be included.
You prevent the file from being included more than once, here
#ifndef HEADER_FILE
you test if HEADER_FILE is NOT defined, in case that's true then
#define HEADER_FILE
would define it, now if you include the file in another file, the first time it will define HEADER_FILE, while the second time, it will be already defined and hence the content of the file is not included again, since the #ifndef HEADER_FILE will be false.
Remember that these are evaluated by the preprocessor before actual compilation is done, so they are evaluated at compile time.
First of all, in modern C++ compile you can use #pragma once instead of include guards.
Then, your example is a little confuse, because you define an extern function in your header. Normally include files are used to define function's declarations and not function's definitions.
If you define functions in your header and if this header is used by more than one CPP source files, this function will be define more times with same name and you will have an error when program will be linked !
A better include would be
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void);
#endif
or
#ifndef HEADER_FILE
#define HEADER_FILE
static int two(void) { return 2; }
#endif
or
#pragma once
static int two(void) { return 2; }
In the last case, function two() is defined in each CPP source files that include this header; but this function is static, so CPP sources are compiled correctly and CPP program is linked without problem.
In your question, you ask
in which case we can also forgot adding #define HEADER_FILE?
Personally, I use same header in very special tricky situation.
The following 2 includes are a "good" example:
/*******************************************************************
* XTrace.Configuration.h
********************************************************************
*/
#pragma once
#define MODULEx(n) extern StructDefineMODULE MODULE_##n;
#include "XTrace.Modules.h"
#undef MODULEx
#define MODULEx(n) { #n, &MODULE_##n } ,
static struct ModuleTRACE tModuleTrace[]
= {
#include "XTrace.Modules.h"
{ 0, 0 }
};
where XTrace.Modules.h include is following
/*******************************************************************
* XTrace.Modules.h
********************************************************************
*/
MODULEx( BBDIXFILE )
MODULEx( CECHO )
MODULEx( INITDBFIELD )
MODULEx( IVIRLUX )
The first include contains #pragma once and call same internal include 2 times.
The first time it is called to define extern declaration of StructDefineMODULE structure.
The second time is is called to initialize an array of ModuleTRACE structures.
Since this include is called 2 times, #pragma once or #ifndef must be avoid.
In using an internal include I'm sure at 100% that all elements used to define StructDefineModule are also used to initialize tModuleTrace[] array.
The include internal result, would be
/*******************************************************************
* XTrace.Configuration.h
********************************************************************
*/
#pragma once
extern StructDefineMODULE MODULE_BBDIXFILE;
extern StructDefineMODULE MODULE_CECHO;
extern StructDefineMODULE MODULE_INITDBFIELD;
extern StructDefineMODULE MODULE_IVIRLUX;
static struct ModuleTRACE tModuleTrace[]
= { { "BBDIXFILE" , &MODULE_BBDIXFILE }
, { "CECHO" , &MODULE_CECHO }
, { "INITDBFIELD" , &MODULE_INITDBFIELD }
, { "IVIRLUX" , &MODULE_IVIRLUX }
, { 0, 0 }
};
I hope that this can help you to understand why, in some situations, include guards can be avoid !