Hello, everyone.

I have a question about "One definition rule" for classes in different
translation units and gcc behaviour. Let us have the following
program:

//------ t1.cpp

#include <stdlib.h>
#include <stdio.h>

class A
{
public:
    A(){printf("1\n");a=1;}
    int a;
};

void foo(void * a)
{
    a = new A;
}

//------ t1.h

void foo(void * a);

//------ t2.cpp

#include <stdlib.h>
#include <stdio.h>

class A
{
public:
    A(){printf("2\n");b=1;}
    int b;
};

void bar(void * a)
{
    a = new A;
}

//------ t2.h

void bar(void * a);

//------ main.cpp

#include "t1.h"
#include "t2.h"

int main()
{
    void * a;
    foo(a);
    bar(a);
}

And now let us see the gcc behaviour (I've tested with gcc-4.6.3 and gcc-4.9.1):

$ g++ *cpp && ./a.out
1
1

$ g++ *cpp -O1 && ./a.out
1
2

As far as I understand the main issue here is that class A has
external linkage and linker do not analyse the fields of class, it
just watches class A by name. And the example itself breaks `3.2 One
definition rule':

> 5.
> ...
> — each definition of D shall consist of the same sequence of tokens


And now my questions:

* am I right with the understanding of situation and the example is UB?
* if two definitions had the same fields and the same constructors,
should the program be correct?
* is correct gcc behaviour with `-O1' a coincidence, or it detects
another class anyway?
* does it make sense to give a warning in that case?


Kind regards,
Markin Alex

Reply via email to