8

Let I've two cpp files:

//--a.cpp--//
class A
{
public:
    void bar()
    {
        printf("class A");
    }
};
//--b.cpp--//
class A
{
public:
    void bar()
    {
        printf("class A");
    }
};

When I'm compling and linking this files together I have no errors. But if I'll write the following:

//--a.cpp--//
int a;
//--b.cpp--//
int a;

After compiling and linking this sources I've an error as the redefiniton of a. But in the case of classes I've redefinition to, but there is no error is raised. I'm confused.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • http://stackoverflow.com/questions/10671956/same-class-name-in-different-c-files same question – coder hacker May 06 '14 at 12:11
  • You could put these class definitions in an unnamed namespace. – John Dibling May 06 '14 at 12:37
  • 1
    @TejasPatel: Actually, the question is different. The one you linked provides a **different definition** whereas in this case this is the **same definition**. – Matthieu M. May 06 '14 at 12:39
  • @MatthieuM. The fact that the two classes happen to be identical in this case makes no difference, both questions cover the same issue. – JAB May 06 '14 at 14:04
  • 1
    @JAB: it makes all the difference. If they are different, you are violating the ODR (One definition rule); whereas if they are identical, it's alright (that's what a `#include` would amount to). – Matthieu M. May 06 '14 at 15:09
  • 1
    @MatthieuM. Oh, it seems you're right. My apologies. – JAB May 06 '14 at 15:11
  • @JAB: no worries, it's quite a subtle difference certainly :x – Matthieu M. May 06 '14 at 15:14

3 Answers3

11

Classes are types. For the most part, they are compile-time artifacts; global variables, on the other hand, are runtime artifacts.

In your first example, each translation unit has its own definition of class a. Since the translation units are separate from each other, and because they do not produce global runtime artifacts with identical names, this is OK. The standard requires that there be exactly one definition of a class per translation unit - see sections 3.2.1 and 3.2.4:

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.

However, the standard permits multiple class definitions in separate translation units - see section 3.2.6:

There can be more than one definition of a class type, enumeration type, inline function with external linkage, class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. [...]

What follows is a long list of requirements, which boils down to that the two class definitions need to be the same; otherwise, the program is considered ill-formed.

In your second example you are defining a global runtime artifact (variable int a) in two translation units. When the linker tries to produce the final output (an executable or a library) it finds both of these, and issues a redefinition error. Note that the rule 3.2.6 above does not include variables with external linkage.

If you declare your variables static, your program will compile, because static variables are local to a translation unit in which they are defined.

Although both programs would compile, the reasons why they compile are different: in case of multiple class definitions the compiler assumes that the two classes are the same; in the second case, the compiler considers the two variables independent of each other.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks for your answer. But can you get a reference or a quote from the c++ standard? –  May 06 '14 at 12:23
  • @DmitryFucintv: C++11 3.2, One Definition Rule, [basic.def.odr]. – Mike Seymour May 06 '14 at 12:30
  • The last paragraph is definitely wrong. Declaring variables `static` results in two different, unrelated variables. Two classes with the same name are the same class, even if they are defined in two different translation units. – James Kanze May 06 '14 at 12:55
  • @JamesKanze I can see how the last paragraph could be misleading. I edited to make sure that the two situations are treated separately. Thanks! – Sergey Kalinichenko May 06 '14 at 13:20
1

Classes can't be used (except in very limited ways) unless the definition is available within the translation unit that uses it. This means that you need multiple definitions in order to use it in multiple units, and so the language allows that - as long as all the definitions are identical. The same rules apply to various other entities (such as templates and inline functions) for which a definition is needed at the point of use.

Usually, you would share the definition by putting it in a header, and including that wherever it's needed.

Variables can be used with only a declaration, not the definition, so there's no need to allow multiple definitions. In your case, you could fix the error by making one of them a pure declaration:

extern int a;

so that there is only one definition. Again, it's common for such declarations to go in headers, to make sure they're the same in every file that uses them.

For the full, gory details of the One Definition Rule, see C++11 3.2, [basic.def.odr].

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • You should probably prefix this with "Because the standard says so. The reason the standard says so is...". – James Kanze May 06 '14 at 12:29
  • 1
    @JamesKanze: Indeed, the pedantic answer to any question about why something is or isn't allowed is "because the standard says so". I don't usually feel the need spell that out, and don't think it would improve this answer. – Mike Seymour May 06 '14 at 12:36
1

There are actually two different flavors of the One Definition Rule.

One flavor, which applies to global and namespace variables, static class members, and functions without the inline keyword, says that there can only be one definition in the entire program. These are the things that typically go in *.cpp files.

The other flavor, which applies to type definitions, functions ever declared with the inline keyword, and anything with a template parameter, says that the definition can appear once per translation unit but must be defined with the same source and have the same meaning in each. It's legal to copy-paste into two *.cpp files as you did, but typically you would put these things in a header file and #include that header from all the *.cpp files that need them.

aschepler
  • 70,891
  • 9
  • 107
  • 161
  • Note the multiple definitions of your first flavor (like the way you described this) result in undefined behavior, and so do not guarantee an error (although this will usually be the case). Also: a nit, but the same source is not required---only the same token sequence. (The definitions can, for example, vary in comments.) – James Kanze May 06 '14 at 12:28