0

I am learning multiple file compilation in C++ and found practice like this:

#ifndef MY_LIB_H
#define MY_LIB_H

void func(int a, int b);

#endif

Some people say that this practice is adopted to avoid repeating declarations. But I try to declare a function twice and the code just runs well without any compilation error (like below).

int func();
int func();
int func()
{
  return 1;
}

So is it really necessary to avoid repeating declarations? Or is there another reason for using #ifndef?

Evg
  • 25,259
  • 5
  • 41
  • 83
Bubble
  • 23
  • 4
  • `#ifndef` is used to prevent double inclusion problem. – foragerDev Mar 12 '22 at 09:13
  • The problem occurs, when you've got the definition of a class or a `constexpr` variable in the header. Also there may be circular includes. You'll also want to limit the amount of parsing the compiler has to do. Even if you're sure including a header multiple times would be fine, you should nonetheless add the header guards; you never know, if you want to add something to the header in the future that may require a header guard and it's all too easy to forget to check, if it was already introduced... – fabian Mar 12 '22 at 09:18
  • You also see more and more the use of `#pragma once` as it avoids problems with name clashes. – Goswin von Brederlow Mar 12 '22 at 12:09
  • It is better to have only one declaration in a header file because if you put multiple declarations around various parts of your code, and you need to change a declaration, you have to hunt around trying to find all the places you made the declarations, rather than just changing it once in a header file. – Galik Mar 12 '22 at 12:26
  • @GoswinvonBrederlow -- `#pragma once` introduces problems with portability. It is not standard, and it is not implementable in some environments. – Pete Becker Mar 12 '22 at 13:18
  • @Galik That is not what the include guard is about. You only have one declaration but it can easily get included multiple times. There is still only one location where the declaration is written down. – Goswin von Brederlow Mar 12 '22 at 13:29
  • @PeteBecker Hopefully that will change for C at some point. For c++ it should be a solved problem with modules. – Goswin von Brederlow Mar 12 '22 at 13:30
  • @PeteBecker Are there any modern compilers that don't implement it? I was under impression that the support for it is ubiquitous. – HolyBlackCat Mar 12 '22 at 13:55
  • @HolyBlackCat -- it's not implementable. The problem is with network servers that can be reached through multiple paths; there's no way to know that `#include "xxx.h"` refers to the same file when it's reached through a different path. – Pete Becker Mar 12 '22 at 14:25

3 Answers3

4

Some people say that this practice is adopted to avoid repeating declarations.

If some people say that then what they say is misleading. Header guards are used to avoid repeating definitions in order to conform to the One Definition Rule.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

Repeating declarations is okay. Repeating definitions is not.

int func(); // declaration
int func(); // declaration; repetition is okay

class X; // declaration
class X; // declaration; repetition is okay

class Y {}; // definition
class Y {}; // definition; repetition is not okay

If a header consists only of declarations it can be included multiple times. But that's inefficient: the compiler has to compile each declaration, determine that it's just a duplicate, and ignore it. And, of course, even if it consists only of declarations at the moment, some future maintainer (including you) will, at some point, change it.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
0

So is it really necessary to avoid repeating declarations?

You can have multiple declarations for a given entity(name). That is you can repeat declarations in a given scope.

is there another reason for using #ifndef?

The main reason for using header guards is to ensure that the second time a header file is #included, its contents are discarded, thereby avoiding the duplicate definition of a class, inline entity, template, and so on, that it may contain.

In other words, so that the program conform to the One Definition Rule(aka ODR).

Jason
  • 36,170
  • 5
  • 26
  • 60