8

I'm making a project, and I get stunned with a problem.

I have 3 libraries.h that includes another special library, definitions.h, but in my Main module, i want to include all the libraries just one time, I mean, I want to test if the library definitions.h has already been included, and include it or not depending on the result.

Something like

If !(#include"definitions.h")
(#include"definitions.h")
Jens
  • 69,818
  • 15
  • 125
  • 179
  • 5
    In C, the header files must protect _themselves_ from multiple inclusion. Something like this: `#ifndef HEADER_H #define HEADER_H ... #endif`. – Vlad Jun 08 '13 at 15:31
  • 1
    One does not `#include` *libraries* but *headers*. *libraries* are linked, after compilation. And even before the latter we `#include`ed the *librarie(s)'* *header(s)* via the pre-processor. – alk Jun 08 '13 at 15:39
  • 1
    This **is** a dupe, isn't it? – alk Jun 08 '13 at 16:33

3 Answers3

18

You are looking for include guards.

Example,

#ifndef DEFINITIONS_H 
#define DEFINITIONS_H 
...
...

#endif
P.P
  • 117,907
  • 20
  • 175
  • 238
  • 1
    +1 for beating me to it. – Kninnug Jun 08 '13 at 15:33
  • 1
    +1 beating me to it...Add some more explanation...it seems the OP needs it... – pinkpanther Jun 08 '13 at 15:33
  • +1 for being faster than me. – hellerve Jun 08 '13 at 15:35
  • +1 for not using identifiers starting with underscore+caps (undefined behavior) – Jens Jun 08 '13 at 16:37
  • Ok, but does it work if one of them exist and another no? It will decline all of them? – aalexren Mar 31 '20 at 11:19
  • @kot_mapku3 hi, it's not clear to me what you're referring to "one of them exist and another no". Can you clarify or give an example? – P.P Apr 01 '20 at 08:35
  • @P.P I mean e.g. (header1 and header2 have a check "ifdef..." etc.) header1.h: #include and #include , header2.h: #include and #include and main.cpp: #include "header2.h" #include "header1.h". Will main.cpp contain both of them or just one of them? Clearly: it will contain 3 headers libraries or 2? – aalexren Apr 01 '20 at 11:46
  • 1
    @kot_mapku3 It'll include both the headers. But since is already included via header2.h, it won't be included via header1.h (as the include guard in will prevent that). So main.cpp will have 3 includes: , , and ). – P.P Apr 01 '20 at 11:58
7
#ifndef DEFINITIONS_H
#define DEFINITIONS_H
//lots of code
//
//
//
//
#endif

There's also non-standard #pragma once, see Is #pragma once a safe include guard?

Community
  • 1
  • 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

If your header syntax is correct, this should not be a problem. In fact, this is the reason why you write

#ifndef _DEFINITIONS_H
#define _DEFINITIONS_H
[header content]
#endif

So, if your header is conform to C conventions, you should be fine.

hellerve
  • 508
  • 1
  • 6
  • 30
  • 1
    OT: Interesting to see that I seem to be the only one using leading underscores for my `#define`. – hellerve Jun 08 '13 at 15:40
  • 1
    This is **undefined behavior** because you are using an identifier starting with underscore+caps. This should be `DEFINITIONS_H`. You seem to be the only one who hasn't seen the light yet :-) – Jens Jun 08 '13 at 16:37
  • Ya. Arn't they kind of meant to be reserved to the compilers namespace? – EvilTeach Jun 08 '13 at 16:38
  • I'm not sure tbh. I trusted Zed Shaw(author of "learn C the hard way") there. He always does it like this and I just adopted it. So, @jens, are you completely sure? – hellerve Jun 08 '13 at 16:49
  • 1
    IOW, leading underscore appears OK as long as it is not followed by an uppercase letter/underscore. Such could be used in the future by the compiler. Ref: C11 draft 16.8.4: "Any other predefined macro names shall begin with a leading underscore followed by an uppercase letter or a second underscore." – chux - Reinstate Monica Jun 08 '13 at 16:55
  • 1
    Yes I'm sure. The C Standards forbids the use of reserved identifiers. Underscore+Caps is always reserved for any use = in any namespace, even in the macro namespace. Shaw is wrong because he just wrote it like he found it in the implementation headers in /usr/include. – Jens Jun 08 '13 at 17:03
  • Thanks for the clarification. Always nice to learn something new. – hellerve Jun 08 '13 at 17:18