1

According to Why can't I multi-declare a class

class A; is a declaration while

class A { ... } is a definition

Typically, in header files, we define the class and we implement its member functions in the .cpp. But wouldn't defining classes in the header file violate the One Definition Rule?

According to https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/

Doesn’t defining a class in a header file violate the one-definition rule?

It shouldn’t. If your header file has proper header guards, it shouldn’t be possible to include the class definition more than once into the same file.

Types (which include classes), are exempt from the part of the one-definition rule that says you can only have one definition per program. Therefore, there isn’t an issue #including class definitions into multiple code files (if there was, classes wouldn’t be of much use).

While the first part is obviously true, header guards will prevent multiple definitions in the same file, but I am confused about the second part of the answer that addresses my question.

If a header file has a definition of a class, for example ThisClass, and that header file is included in two other files for example a.cpp and b.cpp. Why wouldn't it violate the One Definition Rule? If a ThisClass object is created in either file, which definition would be called?

csguy
  • 1,354
  • 2
  • 17
  • 37
  • 1
    The functions will be inline if defined inside the class definition. – drescherjm Dec 30 '19 at 18:47
  • 1
    The header guard part is the wrong reason. You are correct to question this. – drescherjm Dec 30 '19 at 18:48
  • @drescherjm I know that class member functions if defined in the header file are inline, but I am still defining a class right? where class ThisClass {}; would appear twice (referencing my ex) – csguy Dec 30 '19 at 18:50
  • Does not violate ODR: _"...each definition consists of the same sequence of tokens (typically, appears in the same header file)..."_ source: https://en.cppreference.com/w/cpp/language/definition – Richard Critten Dec 30 '19 at 18:54
  • @RichardCritten is that saying that if the definitions are identical, ODR isn't violated? (not familiar with meaning of tokens) – csguy Dec 30 '19 at 18:58
  • Note: There can be more than one definition in a program of each of the following: class type, enumeration type, inline function, inline variable (since C++17), templated entity (template or member of template, but not full template specialization), as long as all of the following is true: ... https://en.cppreference.com/w/cpp/language/definition – csguy Dec 30 '19 at 19:01
  • Does this answer your question? [Why is there no multiple definition error when you define a class in a header file?](https://stackoverflow.com/questions/14654377/why-is-there-no-multiple-definition-error-when-you-define-a-class-in-a-header-fi) – JaMiT May 22 '23 at 03:07

3 Answers3

2

If a header file has a definition of a class, for example ThisClass, and that header file is included in two other files for example a.cpp and b.cpp. Why wouldn't it violate the One Definition Rule?

Because, as you quoted, the one definition rule specifically allows for this.

How can it? Read on…

If a ThisClass object is created in either file, which definition would be called?

It doesn't matter, because the definitions are required to be absolutely, lexically identical.

If they're not, your program has undefined behaviour and you can expect all manner of weirdness to ensue.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

Based on what I'm reading, it might be important to use Wikipedia's brief explanation of what the One Definition Rule actually is:

The One Definition Rule (ODR) is an important rule of the C++ programming language that prescribes that objects and non-inline functions cannot have more than one definition in the entire program and template and types cannot have more than one definition by translation unit.

This means that when the program is compiled, there can be one, and only one definition of a function or object. This might be confusing, however a class or type shouldn't be thought of as objects, they're really just blueprints for an object.

In your question, I think there's a misunderstanding of what #include does and how the ODR applies to classes. When the program is compiling, the .cpp files look to their #include'd class definitions as a way to link together, that is, the class.h blueprint must know where to look when calling it's member functions. Having multiple #include's of the same class.h is not the same as having multiple definitions of class.h, and thus, it cannot violate the One Definition Rule.

alteredinstance
  • 587
  • 3
  • 17
  • 2
    That's not true - the ODR specifically calls out this case as being permitted, and it absolutely falls under the ODR's jurisdiction. I don't think the OP misunderstood anything. – Lightness Races in Orbit Dec 30 '19 at 19:12
  • 1
    OP is confused as to why multiple `#include`s of a `class.h` in two or more `classa.cpp`, and `classb.cpp` don't violate the ODR. The reason that it does not violate the rule is because it only ever has one definition - the compiler essentially just sews the .cpp and .h files together and they become a single definition. OP misunderstands that `#include` is not re-defining the class, it is merely **linking** it. – alteredinstance Dec 30 '19 at 19:25
  • 2
    No, they are talking about the case of multiple translation units. Even if they weren't, there is no "sewing"/"linking" in the way that you describe ("they become a single definition" what?). You misunderstood the question. – Lightness Races in Orbit Dec 30 '19 at 19:31
  • _"If a header file has a definition of a class, for example ThisClass, and that header file is included in two other files for example a.cpp and b.cpp."_ That's **two** translation units. – Lightness Races in Orbit Dec 30 '19 at 19:58
0

It is okay to have a class defined in a header file because the compiler treats the functions declared in the class in such a case as an inline functions.

So there are two options to happen when you call this class functions:

Or it wiil inline the function calls and in such a case there is no problem at all of multiple definition.

Or it wont inline them and in such a case he will create the symbols related to the functions as weak symbols. Then the linker will choose one of the symbols to be the symbol representing the function.

Of course if there will be different defintions in two or more cpp files there will be undefined behaviour.

roy cabouly
  • 487
  • 4
  • 12