私はg++
、特にリンク(C ++)オブジェクトファイルのいくつかの境界を理解しようとしてきました。質問する前に、できるだけ圧縮しようとした次の好奇心を見つけました。
コード
ファイルcommon.h
#ifndef _COMMON_H
#define _COMMON_H
#include <iostream>
#define TMPL_Y(name,T) \
struct Y { \
T y; \
void f() { \
std::cout << name << "::f " << y << std::endl; \
} \
virtual void vf() { \
std::cout << name << "::vf " << y << std::endl; \
} \
Y() { \
std::cout << name << " ctor" << std::endl; \
} \
~Y() { \
std::cout << name << " dtor" << std::endl; \
} \
}
#define TMPL_Z(Z) \
struct Z { \
Y* y; \
Z(); \
void g(); \
}
#define TMPL_Z_impl(name,Z) \
Z::Z() { \
y = new Y(); \
y->y = name; \
std::cout << #Z << "(); sizeof(Y) = " << sizeof(Y) << std::endl; \
} \
void Z::g() { \
y->f(); \
y->vf(); \
}
#endif
a.cpp
でコンパイルされたファイルg++ -Wall -c a.cpp
#include "common.h"
TMPL_Y('a',char);
TMPL_Z(Za);
TMPL_Z_impl('a',Za);
b.cpp
でコンパイルされたファイルg++ -Wall -c b.cpp
#include "common.h"
TMPL_Y('b',unsigned long long);
TMPL_Z(Zb);
TMPL_Z_impl('b',Zb);
main.cpp
コンパイルおよびリンクされたファイルg++ -Wall a.o b.o main.cpp
#include "common.h"
struct Y;
TMPL_Z(Za);
TMPL_Z(Zb);
int main() {
Za za;
Zb zb;
za.g();
zb.g();
za.y = zb.y;
return 0;
}
結果./a.out
は
a ctor
Za(); sizeof(Y) = 8
a ctor // <- mayhem
Zb(); sizeof(Y) = 12
a::f a
a::vf a
a::f b // <- mayhem
a::vf b // <- mayhem
質問
さて、私はリンクを試みて一緒g++
にしようとするために私にいくつかの厄介な名前を呼ぶことを期待していました。特にの割り当ては悪です。それはまったく文句を言わないだけでなく、同じ名前()の互換性のない型をリンクさせたいだけでなく、 (resp。)の2次定義を完全に無視します。a.o
b.o
za.y = zb.y
g++
Y
b.o
b.cpp
私はこれまでのところフェッチされた何かをしていないことを意味します。2つのコンパイルユニットがローカルクラスに同じ名前を使用できることは非常に合理的です。大規模なプロジェクトで。
これはバグですか?誰かがこの問題に光を当てることができますか?