Click to See Complete Forum and Search --> : Confused about ODR (One Definition Rule)


MrDoomMaster
April 17th, 2008, 09:49 AM
Hi,

At the wikipedia page located here (http://en.wikipedia.org/wiki/One_Definition_Rule), it states the following in regards to the definition of ODR:

"# In any translation unit, a template, type, function, or object can have no more than one definition. Some of these can have any number of declarations. A definition provides an instance."

This doesn't make sense at all to me. The linker shouldn't allow you to have multiple definitions for something in the same translation unit anyway (it would complain about duplicate symbols). I basically am so confused about this definition that I really don't know what to think.

If anyone could clarify the definition above I'd appreciate it. Thank you.

Lindley
April 17th, 2008, 10:23 AM
You seem to have a handle on it.....duplicate symbols are bad. That's essentially what it's saying.

MrDoomMaster
April 17th, 2008, 12:29 PM
But, it's more than just bad... it's illegal. You can't possibly successfully compile and link your application with duplicate symbols.

If I have a header, for example, that has a static function in it, by including that header in more than one translation unit, I now have duplicate definitions, since for each translation unit the entire function is copied, so when your application is built you have duplicate functions in the executable. The nature of statics seems to break this rule.

Graham
April 17th, 2008, 02:04 PM
No, they're in different translation units. Think of it as the compiler mangling the function name with an extra bit that's unique to the translation unit (that's essentially what happens when you declare a member function - the name gets mangled based on the name of the owning class and the function's parameters).

The wikipedia entry is referring to multiple definitions in a single translation unit. If you included your header (assuming no inclusion guards) twice in one cpp file, then you would get a compiler error indicating the duplication.


// A.cpp

static void f() // this name gets mangled to, e.g. void f_0_a_cpp()
{
// stuff
}

static void f(int i) // -> void f_int_a_cpp
{
// stuff
}

//////

// B.cpp

static void f() // -> void f_0_b_cpp() (no clash with a.cpp's f() )
{
// stuff
}
//////////

// C.cpp

static void f() // -> void f_0_c_cpp()
{
// stuff
}

static void f() // gets mangled to the same as the above - error
{
//
}