Include Guards in C
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
add a comment |
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
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
add a comment |
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
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
c ifndef
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
add a comment |
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
add a comment |
3 Answers
3
active
oldest
votes
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.)
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 bestruct 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 theConfig
defined bytypedef
.struct Config_t;
is an incomplete type that will be completed once the fullstruct Config_t { ... };
is encountered. Thevoid somePrintingFunction(struct Config_t *conf);
declaration is fine even ifstruct 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
add a comment |
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.h
a 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.
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
add a comment |
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);
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
|
show 1 more comment
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.)
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 bestruct 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 theConfig
defined bytypedef
.struct Config_t;
is an incomplete type that will be completed once the fullstruct Config_t { ... };
is encountered. Thevoid somePrintingFunction(struct Config_t *conf);
declaration is fine even ifstruct 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
add a comment |
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.)
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 bestruct 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 theConfig
defined bytypedef
.struct Config_t;
is an incomplete type that will be completed once the fullstruct Config_t { ... };
is encountered. Thevoid somePrintingFunction(struct Config_t *conf);
declaration is fine even ifstruct 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
add a comment |
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.)
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.)
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 bestruct 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 theConfig
defined bytypedef
.struct Config_t;
is an incomplete type that will be completed once the fullstruct Config_t { ... };
is encountered. Thevoid somePrintingFunction(struct Config_t *conf);
declaration is fine even ifstruct 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
add a comment |
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 bestruct 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 theConfig
defined bytypedef
.struct Config_t;
is an incomplete type that will be completed once the fullstruct Config_t { ... };
is encountered. Thevoid somePrintingFunction(struct Config_t *conf);
declaration is fine even ifstruct 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
add a comment |
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.h
a 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.
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
add a comment |
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.h
a 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.
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
add a comment |
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.h
a 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.
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.h
a 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.
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
add a comment |
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
add a comment |
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);
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
|
show 1 more comment
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);
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
|
show 1 more comment
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);
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);
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
|
show 1 more comment
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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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