Two class definitions in different translation units

2014-10-28 Thread Alex Markin
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 
#include 

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 
#include 

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


Question about aliases

2012-11-06 Thread Alex Markin
Hello.

I've been watching the sources of aliasing in gcc and found one
comment, that seemed to me a bit strange. In file `gcc/alias.c' in
function `get_alias_set':

>   /* From the former common C and C++ langhook implementation:
>
>  Unfortunately, there is no canonical form of a pointer type.
>  In particular, if we have `typedef int I', then `int *', and
>  `I *' are different types.  So, we have to pick a canonical
>  representative.  We do this below.
>
>  Technically, this approach is actually more conservative that
>  it needs to be.  In particular, `const int *' and `int *'
>  should be in different alias sets, according to the C and C++
>  standard, since their types are not the same, and so,
>  technically, an `int **' and `const int **' cannot point at
>  the same thing.

Please, can you explain the following:

According to the standard

> A typedef declaration does not introduce a new type, only a synonym for the 
> type so specified.

So, as I understand in this case `I *' and `int *' should be equal types?


Also, according to the issue 6.5 (7), we cat access to an object value
with expression that has

> a qualified version of a type compatible with the effective type of the object

So, `const int *' can legally point to the `int *' but not in reverse
order, and that's why `const int *' and `int *' should be in different
alias sets?


Alex.