0

In a not-so-tiny project (>100 .h), I want to make sure that every .h use different include-guards (#ifndef XXX).

Whenever I violate it, I want to be informed as soon as possible.

Situation

Here is the convention I am using (semi-auto-generated, VS2015):-

Foo.h

#ifndef Foo_h__
#define Foo_h__
//....... some long code .........
#endif //Foo_h__

Sometimes (once per 1-4 weeks), after I created new files, copy-and-paste sources or refactor(rename) extensively, I make some mistakes about the include guard. As a result :-

  • Include guard does not match with file name anymore.
  • Include guard happens to be same as another include guard in another header.

Question

How to prevent and cure duplication of include guards?

My poor solution

Solution 1:-

#pragma once

Disadvantage: It is compiler specific. I don't want my code to be compiler-dependent.

Solution 2:-

(Edited, thank Benjamin Lindley and Beta.)

I may code an auto-code-generation script. This is a possible standard:-

<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED

Disadvantage: It required an external script.

Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67
  • That second solution doesn't require Boost. It just uses the same convention that Boost uses. All it requires is a keyboard and knowledge of the path of the file you are editing. – Benjamin Lindley Jan 23 '17 at 02:39
  • I use a guid on the end of the file name. – Richard Critten Jan 23 '17 at 02:42
  • @Benjamin Lindley My mistake, thank. Is the second solution it auto-generated? Can I just paste it? I will investigate more. – javaLover Jan 23 '17 at 02:42
  • @javaLover: It can certainly be auto-generated, if you have a decent text editor. – Benjamin Lindley Jan 23 '17 at 02:43
  • @Benjamin Lindley How about VS2015? – javaLover Jan 23 '17 at 02:43
  • How about a script to verify that the variable name is correct, executed on all header files from time to time? Do you have any preference for a particular scripting language? – Beta Jan 23 '17 at 02:44
  • 4
    Just use `#pragma once`. Avoid the few (if any now) compilers that don't support it. It's not at all compiler specific, it's just not part of the official standard. – Cheers and hth. - Alf Jan 23 '17 at 02:44
  • @javaLover: I couldn't tell you. I haven't used Visual Studio as an editor in a long time. – Benjamin Lindley Jan 23 '17 at 02:46
  • @Beta python or PHP – javaLover Jan 23 '17 at 02:46
  • @Benjamin Lindley An expert doesn't use VS, I think it somehow implies that VS is bad ... What IDE do you use? – javaLover Jan 23 '17 at 02:47
  • If you feel that just cannot use the natural `#pragma once` solution, e.g. because you plan to use an ages old IBM compiler, well then generate UUIDs. It's ugly but it gets the job done. – Cheers and hth. - Alf Jan 23 '17 at 02:47
  • @Cheers and hth. No, I want to developer a program on modern hardware. You mean most standard compilers use `#pragma once`? Can you give a link/reference/evident about this? – javaLover Jan 23 '17 at 02:48
  • @javalover: there's a discussion in Wikipedia. or was. probably still there. oh, i [found it](https://en.wikipedia.org/wiki/Pragma_once). there's evidently a compiler called "portland group c/c++" that doesn't support. – Cheers and hth. - Alf Jan 23 '17 at 02:49
  • @javaLover: I did not mean to imply that VS is bad. The main reason I don't use it is because it takes too long to start up. Presumably this start up time allows it to provide a bunch of features which I don't personally need. I use Sublime. – Benjamin Lindley Jan 23 '17 at 02:49
  • @Cheers and hth. - Alf I [found it](https://en.wikipedia.org/wiki/Pragma_once), thank. However, "not standard" still scares me. – javaLover Jan 23 '17 at 02:51
  • 1
    the c++ standardization committee isn't into the thing about standardizing existing practice. they prefer to innovate. but if you really love java, then you love a language where *everything* is non-standard: java has a language spec, originally from Sun, but has never been standardized. so, assuming the nick reflects your background, you shouldn't be scared of *de facto* standards. ;-) – Cheers and hth. - Alf Jan 23 '17 at 02:52
  • @Cheers and hth. - Alf "isn't into the thing about standardizing existing practice" That is a valuable statement! Where did you get this idea from? .... I just want to make sure before I believe and throw all of my code into it. It seems to be a solution. You can also post as answer, if you want. – javaLover Jan 23 '17 at 02:54
  • 1
    i started observing the standardization process in the mid 1990s. i stopped with c++11. there are cases of existing practice being adopted, mainly via the Boost library. but mostly, the committee innovates. the original standardization in 1998 made all C++ textbooks invalid overnight. it took some years before compiler vendors and authors caught up. – Cheers and hth. - Alf Jan 23 '17 at 02:59
  • 1
    And some never did. – user4581301 Jan 23 '17 at 03:21
  • 1
    Have you taken a look at [C++ "Modules"](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4465.pdf)? There appears to be some [support for modules in VS 2015](https://blogs.msdn.microsoft.com/vcblog/2015/12/03/c-modules-in-vs-2015-update-1/). Unfortunately it doesn't appear that modules made it into C++17. I think if I weren't in an all MS VS shop, I'd probably just continue with include guards for the time being and maybe use a script on code upload to check for their uniqueness if it was becoming a problem. – Louis Langholtz Jan 23 '17 at 05:45
  • `#pragma once` **is** covered by the standard. Like all `#pragma` directives, it's effect is implementation defined [`[cpp.pragma]`](http://eel.is/c++draft/cpp.pragma) – Caleth Aug 03 '18 at 09:37

1 Answers1

0

As #pragma once is not fully portable my advice is to run before building procedures this simple bash script:

find . -name '*.h' -o -name '*.hpp' | xargs -n1 -d '\n' grep "#ifndef .*_H.*" | sort | uniq -cd

It eventually shows how many files use the same include guards and the exact include guards which is repeated by error.

fiorentinoing
  • 948
  • 12
  • 20