Include Guards in C












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 '18 at 13:30











  • yes sorry, it's typo. In my code it's #define

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:51
















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 '18 at 13:30











  • yes sorry, it's typo. In my code it's #define

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:51














1












1








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 '18 at 13:59







BeGreen

















asked Nov 22 '18 at 13:25









BeGreenBeGreen

139118




139118








  • 2





    shouldn't be #define ? You are using #def.

    – Loufi
    Nov 22 '18 at 13:30











  • yes sorry, it's typo. In my code it's #define

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:51














  • 2





    shouldn't be #define ? You are using #def.

    – Loufi
    Nov 22 '18 at 13:30











  • yes sorry, it's typo. In my code it's #define

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:51








2




2





shouldn't be #define ? You are using #def.

– Loufi
Nov 22 '18 at 13:30





shouldn't be #define ? You are using #def.

– Loufi
Nov 22 '18 at 13:30













yes sorry, it's typo. In my code it's #define

– BeGreen
Nov 22 '18 at 13:30





yes sorry, it's typo. In my code it's #define

– BeGreen
Nov 22 '18 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 '18 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 '18 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 '18 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 '18 at 13:51












3 Answers
3






active

oldest

votes


















4














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 '18 at 13:46











  • But I'll get a redefinition of Config?

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:55













  • @IanAbbott Thanks. I hadn't noticed that.

    – PSkocik
    Nov 22 '18 at 13:57



















3














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 '18 at 13:52











  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

    – Yastanub
    Nov 22 '18 at 13:58



















2














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 '18 at 13:32











  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

    – PSkocik
    Nov 22 '18 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 '18 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 '18 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 '18 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',
autoActivateHeartbeat: false,
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









4














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 '18 at 13:46











  • But I'll get a redefinition of Config?

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:55













  • @IanAbbott Thanks. I hadn't noticed that.

    – PSkocik
    Nov 22 '18 at 13:57
















4














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 '18 at 13:46











  • But I'll get a redefinition of Config?

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:55













  • @IanAbbott Thanks. I hadn't noticed that.

    – PSkocik
    Nov 22 '18 at 13:57














4












4








4







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 '18 at 13:56

























answered Nov 22 '18 at 13:44









PSkocikPSkocik

34k65476




34k65476








  • 1





    I did not know C11 had that improvement. Nice.

    – StoryTeller
    Nov 22 '18 at 13:46











  • But I'll get a redefinition of Config?

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:55













  • @IanAbbott Thanks. I hadn't noticed that.

    – PSkocik
    Nov 22 '18 at 13:57














  • 1





    I did not know C11 had that improvement. Nice.

    – StoryTeller
    Nov 22 '18 at 13:46











  • But I'll get a redefinition of Config?

    – BeGreen
    Nov 22 '18 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 '18 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 '18 at 13:55













  • @IanAbbott Thanks. I hadn't noticed that.

    – PSkocik
    Nov 22 '18 at 13:57








1




1





I did not know C11 had that improvement. Nice.

– StoryTeller
Nov 22 '18 at 13:46





I did not know C11 had that improvement. Nice.

– StoryTeller
Nov 22 '18 at 13:46













But I'll get a redefinition of Config?

– BeGreen
Nov 22 '18 at 13:49





But I'll get a redefinition of Config?

– BeGreen
Nov 22 '18 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 '18 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 '18 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 '18 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 '18 at 13:55















@IanAbbott Thanks. I hadn't noticed that.

– PSkocik
Nov 22 '18 at 13:57





@IanAbbott Thanks. I hadn't noticed that.

– PSkocik
Nov 22 '18 at 13:57













3














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 '18 at 13:52











  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

    – Yastanub
    Nov 22 '18 at 13:58
















3














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 '18 at 13:52











  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

    – Yastanub
    Nov 22 '18 at 13:58














3












3








3







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 '18 at 14:13









StoryTeller

100k12204272




100k12204272










answered Nov 22 '18 at 13:40









YastanubYastanub

578314




578314













  • The question is tagged C.

    – Lundin
    Nov 22 '18 at 13:52











  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

    – Yastanub
    Nov 22 '18 at 13:58



















  • The question is tagged C.

    – Lundin
    Nov 22 '18 at 13:52











  • @Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

    – Yastanub
    Nov 22 '18 at 13:58

















The question is tagged C.

– Lundin
Nov 22 '18 at 13:52





The question is tagged C.

– Lundin
Nov 22 '18 at 13:52













@Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

– Yastanub
Nov 22 '18 at 13:58





@Lundin whoops i corrected the fily types. The C-Preprocessor should remain the same anyway.

– Yastanub
Nov 22 '18 at 13:58











2














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 '18 at 13:32











  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

    – PSkocik
    Nov 22 '18 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 '18 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 '18 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 '18 at 13:43


















2














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 '18 at 13:32











  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

    – PSkocik
    Nov 22 '18 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 '18 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 '18 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 '18 at 13:43
















2












2








2







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 '18 at 13:35

























answered Nov 22 '18 at 13:32









StoryTellerStoryTeller

100k12204272




100k12204272













  • And the compiler will understand that it's not Config_t from debug.h but from a.h?

    – BeGreen
    Nov 22 '18 at 13:32











  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

    – PSkocik
    Nov 22 '18 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 '18 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 '18 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 '18 at 13:43





















  • And the compiler will understand that it's not Config_t from debug.h but from a.h?

    – BeGreen
    Nov 22 '18 at 13:32











  • @BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

    – PSkocik
    Nov 22 '18 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 '18 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 '18 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 '18 at 13:43



















And the compiler will understand that it's not Config_t from debug.h but from a.h?

– BeGreen
Nov 22 '18 at 13:32





And the compiler will understand that it's not Config_t from debug.h but from a.h?

– BeGreen
Nov 22 '18 at 13:32













@BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

– PSkocik
Nov 22 '18 at 13:34





@BeGreen The compiler doesn't need to care. All struct pointers are guaranteed to look the same.

– PSkocik
Nov 22 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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.




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

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

RAC Tourist Trophy