Is it possible to write a header file without enabling security and without multiple definition errors?

Just out of curiosity I wanted to know if there is a way to achieve this.

In C ++, we learn that we should avoid using macros. But when we use include guard, we use at least one macro. So I was wondering if there is a way to write a program without macros.

+3


source to share


5 answers


This is definitely doable, and I used some early C ++ libraries that followed an already flawed approach from C that essentially required the user of the header to include some other headers before that. This is based on a careful understanding of what creates the dependency on what else and to use declarations rather than definitions where possible:

  • Declarations can be repeated multiple times, although it is obvious that they must be consistent, and some objects cannot be declared (for example, enum

    can only be defined, in C ++ 2011 you can also declare enum

    s).
  • The definitions cannot be repeated, but are only needed if the definition is actually used. For example, using a pointer or reference to a class does not need to be defined, but only declared.

Thus, the approach to writing headers would be to try to avoid definitions as much as possible and make the most of the declaration: they might be repeated in the header file, or the corresponding headers might even be included multiple times. The basic need for definitions comes when you need to get the base class: this cannot be avoided and essentially means that the user will have to include the header for the base class before using any of the derived classes. The same is true for members defined directly in the class, but using pimpl-idiom, the need for member definitions can be moved to the implementation file.



While there are some advantages to this approach, it also has several serious disadvantages. The main advantage is that it kind of provides very careful separation and management of dependencies. On the other hand, overly aggressive partitioning, such as using pimpl-idiom for everything, also negatively impacts performance. The biggest drawback is that many of the implementation details are implicitly visible to the user of the header, because the corresponding headers of this depend on being included explicitly in the first place. At the very least, the compiler makes sure you get the order of the included files correctly.

In terms of usability and dependency, I believe there is a general consensus that headers are best self-contained and that using guards is the lesser evil.

+1


source


This is definitely possible, although it is unimaginably bad practice not to include guards. It is important to understand what the #include statement does: the content of another file is inserted directly into the source file before it is compiled. The protective shell prevents re-entering the same code.

Including a file only fails if it would be wrong to enter the contents of that file in the place where you included it. For example, you can declare (note: declare, not define) the same function (or class) multiple times in the same compilation unit. If your header file consists only of declarations, you do not need to include a protective wrapper.

IncludedFile.h

class SomeClassSomewhere;
void SomeExternalFunction(int x, char y);

      

main.cpp



#include "IncludedFile.h"
#include "IncludedFile.h"
#include "IncludedFile.h"

int main(int argc, char **argv)
{
    return 0;
}

      

When declaring a function (or class) multiple times, it is normal, it is not possible to define the same function (or class) more than once. If there are two or more definitions for a function, the linker does not know which one to choose and discards the "multiple symbols defined" error.

It is very common in C ++ to include class definitions for headers. The include guard prevents the #included file from being inserted into the source file a second time, which means your definitions will only appear once in compiled code and the linker will not be confused.

Instead of trying to figure out when you need to use them and when not, always use include guard. In most cases, avoiding most macros is a good idea; this is one of the situations where they are not evil and it is not dangerous to use them here.

+3


source


This can be done if you ensure that the same header file will not be included in the same translation unit multiple times.

Alternatively, you can use:

#pragma once

      

If portability isn't your problem.

However, you shouldn't use # pragma once over Enable Guardians , because:

  • It is not standard and therefore not portable.
  • It is less intuitive and not all users might know.
  • This does not have much advantage over the classic and very famous Include Guard.
+1


source


In short, yes, even without pragmas. Only if you can guarantee that each header file is included only once. However, given that the code tends to grow, it becomes more difficult to maintain this guarantee as the number of header files increases. This is why it is considered bad practice to use header defenders.

Pre-processor macros are incredulous, yes. However, the header includes guards - this is a necessary evil because the alternative is much worse (#pragma will only work once if your compiler supports it, so you lose portability)

When it comes to preprocessor macros, use this rule: If you can think of an elegant solution that doesn't include a macro, then avoid them.

+1


source


Is there a non-portable, non-standard

#pragma once

      

good enough for you? Personally, I would rather use macros to prevent re-inclusion, but this is your solution.

0


source







All Articles