We help IT Professionals succeed at work.

Question about One Definition Rule

Nusrat Nuriyev
on
Hello dear EE-ers,

There is a quote:
In the entire program, an object or non-inline function cannot have more than one definition; if an object or function is used, it must have exactly one definition. You can declare an object or function that is never used, in which case you don't have to provide a definition. In no event can there be more than one definition.

Please, provide example about this statement, especially regarding "in no even can there be more that one definition".

Thanks.
Comment
Watch Question

jkr
Top Expert 2012
Commented:
Since 'definition' is used as a supplement to 'implementation', that statement speaks for itself. One thing is missing though, while multiple definitions (implementations) are an obvious problem, multiple declarations might hit as well.

Since you asked for examples:

//all fine, one declaration and one definition for each one
void print(const string& data);
void print(const string& data1, const string& data2);

void print(const string& data) {
  cout << data << endl;
}
void print(const string& data1, const string& data2) {
  cout << data << " " << data2 << endl;
}

Open in new window

// Houston, we have a problem
void print(const string& data);

void print(const string& data) {
  cout << data << endl;
}
void print(const string& data) {
  cerr << data << endl;
}

Open in new window

Further Learning Resource
Google Code
One Definition Rule Violation

Author

Commented:
So, definition is more general term than implementation and in case of C programming language definition is reduced to implementation, correct?

Author

Commented:
@Akashay K
Thanks for ODR violation,  could you please provide something that I can test to violate in gcc compiler?
jkr
Top Expert 2012

Commented:
>>So, definition is more general term than implementation and in case of C programming language definition is reduced to
>>implementation, correct?

Indeed. I'd usually also go by the term 'implementation', but 'definition' here means the same and also covers instances and variables.

Author

Commented:
I have got it, if we say
int i = 6; //integer i implements number 6

Open in new window

, it sounds a bit weird :)

Defining instances of class?

Author

Commented:
//tu1.cpp
struct X {
    X(int);
    X(int, int);
};
X::X(int = 0) { }
class D: public X {};
D d2;


int main(){}

Open in new window

//tu2.cpp
struct X {
    X(int);
    X(int, int);
};
X::X(int = 0, int = 0) {}
class D: public X { };

Open in new window


g++ tu1.cpp tu2.cpp
compiles like a charm.
Top Expert 2012
Commented:
Yes, because exist independently in two different compilation units that don't cross-reference each other.

Author

Commented:
jkr, Could you modify this links in order to make them cross reference? Still don't get this.
jkr
Top Expert 2012

Commented:
The problem about doing so is that it would defy the very purpose of your example. E.g.

// X.h
struct X {
    X(int);
    X(int, int);

Open in new window

// tu1.cpp
#include "X.h"
X::X(int = 0) { }
class D: public X {};
D d2;

Open in new window

#include "X.h"
X::X(int = 0) {int i = i;}
class D: public X { };

Open in new window

which correctly yields
$ g++ tu1.cpp tu2.cpp
/tmp/cc9v8yr7.o:tu2.cpp:(.text+0x0): multiple definition of `X::X(int)'
/tmp/ccsPYguC.o:tu1.cpp:(.text+0x0): first defined here
/tmp/cc9v8yr7.o:tu2.cpp:(.text+0x0): multiple definition of `X::X(int)'
/tmp/ccsPYguC.o:tu1.cpp:(.text+0x0): first defined here
You have omitted  some closed curly braces and semicolons :) But it's okay, I know you quite for long time :)
//tu1.cpp

#include "X.h"
X::X(int = 0) {};
class D: public X {};
D d2;       

Open in new window


//tu1.cpp
#include "X.h"
X::X(int = 0) { int i = i;}
class D: public X {};

Open in new window


To keep the knowledge base clean (as sarabande suggested), I will accept my own answer also as a Solution :)

Author

Commented:
Some minor bugs have been fixed in expert's answer.