Include Guards in C











up vote
1
down vote

favorite
1












I have 2 header files that have to include one other.



config.h:



#ifndef CONFIG
#define CONFIG

#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;
#endif


debug.h



#ifndef DEBUG
#define DEBUG

#include "config.h"

void somePrintingFunction(Config* conf);
#endif


Here is the error I get:




debug.h: error: unknown type name 'Config'



config.c: warning: implicit declaration of function 'somePrintingFunction'



debug.h: error: unknown type name 'Config'




I guess it's looping in the header declaration?





Edit:



Fixed in merging both files so simplify project design. If you want a real fix check in comments.










share|improve this question




















  • 2




    shouldn't be #define ? You are using #def.
    – Loufi
    Nov 22 at 13:30










  • yes sorry, it's typo. In my code it's #define
    – BeGreen
    Nov 22 at 13:30










  • You get warning message from config.c, but you haven't shown it. Please create Minimal, Complete, and Verifiable example.
    – user694733
    Nov 22 at 13:35






  • 3




    There exists no scenario where 2 header files need to include each other. Your program design is confused and the only correct solution is to fix the program design.
    – Lundin
    Nov 22 at 13:51















up vote
1
down vote

favorite
1












I have 2 header files that have to include one other.



config.h:



#ifndef CONFIG
#define CONFIG

#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;
#endif


debug.h



#ifndef DEBUG
#define DEBUG

#include "config.h"

void somePrintingFunction(Config* conf);
#endif


Here is the error I get:




debug.h: error: unknown type name 'Config'



config.c: warning: implicit declaration of function 'somePrintingFunction'



debug.h: error: unknown type name 'Config'




I guess it's looping in the header declaration?





Edit:



Fixed in merging both files so simplify project design. If you want a real fix check in comments.










share|improve this question




















  • 2




    shouldn't be #define ? You are using #def.
    – Loufi
    Nov 22 at 13:30










  • yes sorry, it's typo. In my code it's #define
    – BeGreen
    Nov 22 at 13:30










  • You get warning message from config.c, but you haven't shown it. Please create Minimal, Complete, and Verifiable example.
    – user694733
    Nov 22 at 13:35






  • 3




    There exists no scenario where 2 header files need to include each other. Your program design is confused and the only correct solution is to fix the program design.
    – Lundin
    Nov 22 at 13:51













up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





I have 2 header files that have to include one other.



config.h:



#ifndef CONFIG
#define CONFIG

#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;
#endif


debug.h



#ifndef DEBUG
#define DEBUG

#include "config.h"

void somePrintingFunction(Config* conf);
#endif


Here is the error I get:




debug.h: error: unknown type name 'Config'



config.c: warning: implicit declaration of function 'somePrintingFunction'



debug.h: error: unknown type name 'Config'




I guess it's looping in the header declaration?





Edit:



Fixed in merging both files so simplify project design. If you want a real fix check in comments.










share|improve this question















I have 2 header files that have to include one other.



config.h:



#ifndef CONFIG
#define CONFIG

#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;
#endif


debug.h



#ifndef DEBUG
#define DEBUG

#include "config.h"

void somePrintingFunction(Config* conf);
#endif


Here is the error I get:




debug.h: error: unknown type name 'Config'



config.c: warning: implicit declaration of function 'somePrintingFunction'



debug.h: error: unknown type name 'Config'




I guess it's looping in the header declaration?





Edit:



Fixed in merging both files so simplify project design. If you want a real fix check in comments.







c ifndef






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 13:59

























asked Nov 22 at 13:25









BeGreen

14116




14116








  • 2




    shouldn't be #define ? You are using #def.
    – Loufi
    Nov 22 at 13:30










  • yes sorry, it's typo. In my code it's #define
    – BeGreen
    Nov 22 at 13:30










  • You get warning message from config.c, but you haven't shown it. Please create Minimal, Complete, and Verifiable example.
    – user694733
    Nov 22 at 13:35






  • 3




    There exists no scenario where 2 header files need to include each other. Your program design is confused and the only correct solution is to fix the program design.
    – Lundin
    Nov 22 at 13:51














  • 2




    shouldn't be #define ? You are using #def.
    – Loufi
    Nov 22 at 13:30










  • yes sorry, it's typo. In my code it's #define
    – BeGreen
    Nov 22 at 13:30










  • You get warning message from config.c, but you haven't shown it. Please create Minimal, Complete, and Verifiable example.
    – user694733
    Nov 22 at 13:35






  • 3




    There exists no scenario where 2 header files need to include each other. Your program design is confused and the only correct solution is to fix the program design.
    – Lundin
    Nov 22 at 13:51








2




2




shouldn't be #define ? You are using #def.
– Loufi
Nov 22 at 13:30




shouldn't be #define ? You are using #def.
– Loufi
Nov 22 at 13:30












yes sorry, it's typo. In my code it's #define
– BeGreen
Nov 22 at 13:30




yes sorry, it's typo. In my code it's #define
– BeGreen
Nov 22 at 13:30












You get warning message from config.c, but you haven't shown it. Please create Minimal, Complete, and Verifiable example.
– user694733
Nov 22 at 13:35




You get warning message from config.c, but you haven't shown it. Please create Minimal, Complete, and Verifiable example.
– user694733
Nov 22 at 13:35




3




3




There exists no scenario where 2 header files need to include each other. Your program design is confused and the only correct solution is to fix the program design.
– Lundin
Nov 22 at 13:51




There exists no scenario where 2 header files need to include each other. Your program design is confused and the only correct solution is to fix the program design.
– Lundin
Nov 22 at 13:51












3 Answers
3






active

oldest

votes

















up vote
4
down vote



accepted










When config.h includes debug.h, debug.h will try to include config.h but since the CONFIG guard macro will already have been defined, the retroactive "include" of config.h will get skipped and the parsing will continue on the next line:



void somePrintingFunction(Config* conf);


without the Config type having been defined.



As StoryTeller has pointed out, you can break the mutual dependency by forward declaring the Config_t struct:



struct Config_t;
void somePrintingFunction(struct Config_t* conf);


Since C11, you can also do the typedef since C11 can handle duplicated typedefs as long as they refer to the same type.



typedef struct Config_t Config;
void somePrintingFunction(Config* conf);


(Forward declarations of aggregates (structs or unions) don't allow you to declare objects of those types (unless a full definition has already been provided) but since C guarantees that all pointers to structs or unions must look the same, they are enough to allow you to start using pointers to those types.)






share|improve this answer



















  • 1




    I did not know C11 had that improvement. Nice.
    – StoryTeller
    Nov 22 at 13:46










  • But I'll get a redefinition of Config?
    – BeGreen
    Nov 22 at 13:49










  • @BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
    – PSkocik
    Nov 22 at 13:53










  • struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
    – Ian Abbott
    Nov 22 at 13:55












  • @IanAbbott Thanks. I hadn't noticed that.
    – PSkocik
    Nov 22 at 13:57


















up vote
3
down vote













The problem with this is the circular inclusion. You are actually including your function before you declare your structure.
Lets say you include config.h(assuming you removed the wrong include a.h the preprocessor does this:



#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol CONFIG so that this file will not be included twice. Then it evaluates the remaining include:



#include "config.h"

void somePrintingFunction(Config* conf);


typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol DEBUG. Since symbol CONFIG is defined it will not include config.ha second time and thus it is finished. Now notice how the declaration of the function is before the declaration of the structure. To solve this use a forward declaration like this



#include "config.h"

struct Config_t;
void somePrintingFunction(struct Config_t* conf);


So the compiler knows what Config is before you use it. Just keep in mind to define all functions that use a predeclared structure or class in the c file because the predeclared object is not a defined one yet but will be in the c file.



EDIT: I should mention that circular inclusion is not a good thing to do and you can usually find another solution which is less sanity risking.






share|improve this answer























  • The question is tagged C.
    – Lundin
    Nov 22 at 13:52










  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
    – Yastanub
    Nov 22 at 13:58


















up vote
2
down vote













debug.h doesn't need the other header. You can define that function just fine with a forward declaration of Config_t alone



struct Config_t;
void somePrintingFunction(struct Config_t* conf);





share|improve this answer























  • And the compiler will understand that it's not Config_t from debug.h but from a.h?
    – BeGreen
    Nov 22 at 13:32










  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
    – PSkocik
    Nov 22 at 13:34










  • @BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
    – StoryTeller
    Nov 22 at 13:34












  • When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
    – BeGreen
    Nov 22 at 13:42










  • @BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
    – StoryTeller
    Nov 22 at 13:43













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432014%2finclude-guards-in-c%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
4
down vote



accepted










When config.h includes debug.h, debug.h will try to include config.h but since the CONFIG guard macro will already have been defined, the retroactive "include" of config.h will get skipped and the parsing will continue on the next line:



void somePrintingFunction(Config* conf);


without the Config type having been defined.



As StoryTeller has pointed out, you can break the mutual dependency by forward declaring the Config_t struct:



struct Config_t;
void somePrintingFunction(struct Config_t* conf);


Since C11, you can also do the typedef since C11 can handle duplicated typedefs as long as they refer to the same type.



typedef struct Config_t Config;
void somePrintingFunction(Config* conf);


(Forward declarations of aggregates (structs or unions) don't allow you to declare objects of those types (unless a full definition has already been provided) but since C guarantees that all pointers to structs or unions must look the same, they are enough to allow you to start using pointers to those types.)






share|improve this answer



















  • 1




    I did not know C11 had that improvement. Nice.
    – StoryTeller
    Nov 22 at 13:46










  • But I'll get a redefinition of Config?
    – BeGreen
    Nov 22 at 13:49










  • @BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
    – PSkocik
    Nov 22 at 13:53










  • struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
    – Ian Abbott
    Nov 22 at 13:55












  • @IanAbbott Thanks. I hadn't noticed that.
    – PSkocik
    Nov 22 at 13:57















up vote
4
down vote



accepted










When config.h includes debug.h, debug.h will try to include config.h but since the CONFIG guard macro will already have been defined, the retroactive "include" of config.h will get skipped and the parsing will continue on the next line:



void somePrintingFunction(Config* conf);


without the Config type having been defined.



As StoryTeller has pointed out, you can break the mutual dependency by forward declaring the Config_t struct:



struct Config_t;
void somePrintingFunction(struct Config_t* conf);


Since C11, you can also do the typedef since C11 can handle duplicated typedefs as long as they refer to the same type.



typedef struct Config_t Config;
void somePrintingFunction(Config* conf);


(Forward declarations of aggregates (structs or unions) don't allow you to declare objects of those types (unless a full definition has already been provided) but since C guarantees that all pointers to structs or unions must look the same, they are enough to allow you to start using pointers to those types.)






share|improve this answer



















  • 1




    I did not know C11 had that improvement. Nice.
    – StoryTeller
    Nov 22 at 13:46










  • But I'll get a redefinition of Config?
    – BeGreen
    Nov 22 at 13:49










  • @BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
    – PSkocik
    Nov 22 at 13:53










  • struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
    – Ian Abbott
    Nov 22 at 13:55












  • @IanAbbott Thanks. I hadn't noticed that.
    – PSkocik
    Nov 22 at 13:57













up vote
4
down vote



accepted







up vote
4
down vote



accepted






When config.h includes debug.h, debug.h will try to include config.h but since the CONFIG guard macro will already have been defined, the retroactive "include" of config.h will get skipped and the parsing will continue on the next line:



void somePrintingFunction(Config* conf);


without the Config type having been defined.



As StoryTeller has pointed out, you can break the mutual dependency by forward declaring the Config_t struct:



struct Config_t;
void somePrintingFunction(struct Config_t* conf);


Since C11, you can also do the typedef since C11 can handle duplicated typedefs as long as they refer to the same type.



typedef struct Config_t Config;
void somePrintingFunction(Config* conf);


(Forward declarations of aggregates (structs or unions) don't allow you to declare objects of those types (unless a full definition has already been provided) but since C guarantees that all pointers to structs or unions must look the same, they are enough to allow you to start using pointers to those types.)






share|improve this answer














When config.h includes debug.h, debug.h will try to include config.h but since the CONFIG guard macro will already have been defined, the retroactive "include" of config.h will get skipped and the parsing will continue on the next line:



void somePrintingFunction(Config* conf);


without the Config type having been defined.



As StoryTeller has pointed out, you can break the mutual dependency by forward declaring the Config_t struct:



struct Config_t;
void somePrintingFunction(struct Config_t* conf);


Since C11, you can also do the typedef since C11 can handle duplicated typedefs as long as they refer to the same type.



typedef struct Config_t Config;
void somePrintingFunction(Config* conf);


(Forward declarations of aggregates (structs or unions) don't allow you to declare objects of those types (unless a full definition has already been provided) but since C guarantees that all pointers to structs or unions must look the same, they are enough to allow you to start using pointers to those types.)







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 at 13:56

























answered Nov 22 at 13:44









PSkocik

31.7k54669




31.7k54669








  • 1




    I did not know C11 had that improvement. Nice.
    – StoryTeller
    Nov 22 at 13:46










  • But I'll get a redefinition of Config?
    – BeGreen
    Nov 22 at 13:49










  • @BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
    – PSkocik
    Nov 22 at 13:53










  • struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
    – Ian Abbott
    Nov 22 at 13:55












  • @IanAbbott Thanks. I hadn't noticed that.
    – PSkocik
    Nov 22 at 13:57














  • 1




    I did not know C11 had that improvement. Nice.
    – StoryTeller
    Nov 22 at 13:46










  • But I'll get a redefinition of Config?
    – BeGreen
    Nov 22 at 13:49










  • @BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
    – PSkocik
    Nov 22 at 13:53










  • struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
    – Ian Abbott
    Nov 22 at 13:55












  • @IanAbbott Thanks. I hadn't noticed that.
    – PSkocik
    Nov 22 at 13:57








1




1




I did not know C11 had that improvement. Nice.
– StoryTeller
Nov 22 at 13:46




I did not know C11 had that improvement. Nice.
– StoryTeller
Nov 22 at 13:46












But I'll get a redefinition of Config?
– BeGreen
Nov 22 at 13:49




But I'll get a redefinition of Config?
– BeGreen
Nov 22 at 13:49












@BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
– PSkocik
Nov 22 at 13:53




@BeGreen You won't in C11 and newer is what I'm saying. Repeating a forward declaration is perfectly OK in all C's. Repeating a typedef to the same time is OK since C11 and in previous versions you might get a warning (especially if you compile with -pedantic).
– PSkocik
Nov 22 at 13:53












struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
– Ian Abbott
Nov 22 at 13:55






struct Config should be struct Config_t to match OP's original code. @BeGreen , Config is being used as a structure tag in this case, which is in a different namespace to the Config defined by typedef. struct Config_t; is an incomplete type that will be completed once the full struct Config_t { ... }; is encountered. The void somePrintingFunction(struct Config_t *conf); declaration is fine even if struct Config_t is incomplete.
– Ian Abbott
Nov 22 at 13:55














@IanAbbott Thanks. I hadn't noticed that.
– PSkocik
Nov 22 at 13:57




@IanAbbott Thanks. I hadn't noticed that.
– PSkocik
Nov 22 at 13:57












up vote
3
down vote













The problem with this is the circular inclusion. You are actually including your function before you declare your structure.
Lets say you include config.h(assuming you removed the wrong include a.h the preprocessor does this:



#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol CONFIG so that this file will not be included twice. Then it evaluates the remaining include:



#include "config.h"

void somePrintingFunction(Config* conf);


typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol DEBUG. Since symbol CONFIG is defined it will not include config.ha second time and thus it is finished. Now notice how the declaration of the function is before the declaration of the structure. To solve this use a forward declaration like this



#include "config.h"

struct Config_t;
void somePrintingFunction(struct Config_t* conf);


So the compiler knows what Config is before you use it. Just keep in mind to define all functions that use a predeclared structure or class in the c file because the predeclared object is not a defined one yet but will be in the c file.



EDIT: I should mention that circular inclusion is not a good thing to do and you can usually find another solution which is less sanity risking.






share|improve this answer























  • The question is tagged C.
    – Lundin
    Nov 22 at 13:52










  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
    – Yastanub
    Nov 22 at 13:58















up vote
3
down vote













The problem with this is the circular inclusion. You are actually including your function before you declare your structure.
Lets say you include config.h(assuming you removed the wrong include a.h the preprocessor does this:



#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol CONFIG so that this file will not be included twice. Then it evaluates the remaining include:



#include "config.h"

void somePrintingFunction(Config* conf);


typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol DEBUG. Since symbol CONFIG is defined it will not include config.ha second time and thus it is finished. Now notice how the declaration of the function is before the declaration of the structure. To solve this use a forward declaration like this



#include "config.h"

struct Config_t;
void somePrintingFunction(struct Config_t* conf);


So the compiler knows what Config is before you use it. Just keep in mind to define all functions that use a predeclared structure or class in the c file because the predeclared object is not a defined one yet but will be in the c file.



EDIT: I should mention that circular inclusion is not a good thing to do and you can usually find another solution which is less sanity risking.






share|improve this answer























  • The question is tagged C.
    – Lundin
    Nov 22 at 13:52










  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
    – Yastanub
    Nov 22 at 13:58













up vote
3
down vote










up vote
3
down vote









The problem with this is the circular inclusion. You are actually including your function before you declare your structure.
Lets say you include config.h(assuming you removed the wrong include a.h the preprocessor does this:



#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol CONFIG so that this file will not be included twice. Then it evaluates the remaining include:



#include "config.h"

void somePrintingFunction(Config* conf);


typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol DEBUG. Since symbol CONFIG is defined it will not include config.ha second time and thus it is finished. Now notice how the declaration of the function is before the declaration of the structure. To solve this use a forward declaration like this



#include "config.h"

struct Config_t;
void somePrintingFunction(struct Config_t* conf);


So the compiler knows what Config is before you use it. Just keep in mind to define all functions that use a predeclared structure or class in the c file because the predeclared object is not a defined one yet but will be in the c file.



EDIT: I should mention that circular inclusion is not a good thing to do and you can usually find another solution which is less sanity risking.






share|improve this answer














The problem with this is the circular inclusion. You are actually including your function before you declare your structure.
Lets say you include config.h(assuming you removed the wrong include a.h the preprocessor does this:



#include "debug.h"

typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol CONFIG so that this file will not be included twice. Then it evaluates the remaining include:



#include "config.h"

void somePrintingFunction(Config* conf);


typedef struct Config_t {
/* some stuff */
} Config;


and defines the symbol DEBUG. Since symbol CONFIG is defined it will not include config.ha second time and thus it is finished. Now notice how the declaration of the function is before the declaration of the structure. To solve this use a forward declaration like this



#include "config.h"

struct Config_t;
void somePrintingFunction(struct Config_t* conf);


So the compiler knows what Config is before you use it. Just keep in mind to define all functions that use a predeclared structure or class in the c file because the predeclared object is not a defined one yet but will be in the c file.



EDIT: I should mention that circular inclusion is not a good thing to do and you can usually find another solution which is less sanity risking.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 at 14:13









StoryTeller

91.7k12182249




91.7k12182249










answered Nov 22 at 13:40









Yastanub

566214




566214












  • The question is tagged C.
    – Lundin
    Nov 22 at 13:52










  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
    – Yastanub
    Nov 22 at 13:58


















  • The question is tagged C.
    – Lundin
    Nov 22 at 13:52










  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
    – Yastanub
    Nov 22 at 13:58
















The question is tagged C.
– Lundin
Nov 22 at 13:52




The question is tagged C.
– Lundin
Nov 22 at 13:52












@Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
– Yastanub
Nov 22 at 13:58




@Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.
– Yastanub
Nov 22 at 13:58










up vote
2
down vote













debug.h doesn't need the other header. You can define that function just fine with a forward declaration of Config_t alone



struct Config_t;
void somePrintingFunction(struct Config_t* conf);





share|improve this answer























  • And the compiler will understand that it's not Config_t from debug.h but from a.h?
    – BeGreen
    Nov 22 at 13:32










  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
    – PSkocik
    Nov 22 at 13:34










  • @BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
    – StoryTeller
    Nov 22 at 13:34












  • When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
    – BeGreen
    Nov 22 at 13:42










  • @BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
    – StoryTeller
    Nov 22 at 13:43

















up vote
2
down vote













debug.h doesn't need the other header. You can define that function just fine with a forward declaration of Config_t alone



struct Config_t;
void somePrintingFunction(struct Config_t* conf);





share|improve this answer























  • And the compiler will understand that it's not Config_t from debug.h but from a.h?
    – BeGreen
    Nov 22 at 13:32










  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
    – PSkocik
    Nov 22 at 13:34










  • @BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
    – StoryTeller
    Nov 22 at 13:34












  • When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
    – BeGreen
    Nov 22 at 13:42










  • @BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
    – StoryTeller
    Nov 22 at 13:43















up vote
2
down vote










up vote
2
down vote









debug.h doesn't need the other header. You can define that function just fine with a forward declaration of Config_t alone



struct Config_t;
void somePrintingFunction(struct Config_t* conf);





share|improve this answer














debug.h doesn't need the other header. You can define that function just fine with a forward declaration of Config_t alone



struct Config_t;
void somePrintingFunction(struct Config_t* conf);






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 at 13:35

























answered Nov 22 at 13:32









StoryTeller

91.7k12182249




91.7k12182249












  • And the compiler will understand that it's not Config_t from debug.h but from a.h?
    – BeGreen
    Nov 22 at 13:32










  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
    – PSkocik
    Nov 22 at 13:34










  • @BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
    – StoryTeller
    Nov 22 at 13:34












  • When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
    – BeGreen
    Nov 22 at 13:42










  • @BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
    – StoryTeller
    Nov 22 at 13:43




















  • And the compiler will understand that it's not Config_t from debug.h but from a.h?
    – BeGreen
    Nov 22 at 13:32










  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
    – PSkocik
    Nov 22 at 13:34










  • @BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
    – StoryTeller
    Nov 22 at 13:34












  • When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
    – BeGreen
    Nov 22 at 13:42










  • @BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
    – StoryTeller
    Nov 22 at 13:43


















And the compiler will understand that it's not Config_t from debug.h but from a.h?
– BeGreen
Nov 22 at 13:32




And the compiler will understand that it's not Config_t from debug.h but from a.h?
– BeGreen
Nov 22 at 13:32












@BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
– PSkocik
Nov 22 at 13:34




@BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.
– PSkocik
Nov 22 at 13:34












@BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
– StoryTeller
Nov 22 at 13:34






@BeGreen - You will need to include the other header when calling the function or defining it. So yes, it will. There can be only one structure definition with a given tag in a valid C program. If there isn't exactly one, you'll have much bigger problems.
– StoryTeller
Nov 22 at 13:34














When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
– BeGreen
Nov 22 at 13:42




When I do this I get some issues in my function. "deferencing pointer to incomplete 'Config " {aka struct Config_t}'
– BeGreen
Nov 22 at 13:42












@BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
– StoryTeller
Nov 22 at 13:43






@BeGreen - I did say you need to include the header with the structure definition when defining the function. In the corresponding *.c file.
– StoryTeller
Nov 22 at 13:43




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432014%2finclude-guards-in-c%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Trompette piccolo

Slow SSRS Report in dynamic grouping and multiple parameters

Simon Yates (cyclisme)