![](/img/trans.png)
[英]ODR violation if template is defined in multiple translation units for different types?
[英]Class defined in different translation units
据我了解,一个类可以在多个翻译单元中定义,只要它们是相同的即可。 考虑到这一点,请考虑以下示例:
//1.cpp
class Foo{
public:
int i;
};
void FooBar();
void BarFoo(){
Foo f;
}
int main(){
FooBar();
BarFoo();
}
//2.cpp
class Foo{
public:
std::string s;
};
void FooBar(){
Foo f;
}
这样编译,我不会崩溃。
如果我进行以下更改:
//1.cpp
Foo FooBar();
//2.cpp
Foo FooBar(){
Foo f;
return f;
}
我崩溃了 为什么一个会导致崩溃,而另一个却不会。 另外,在第一个示例中我是否没有违反ODR? 如果是的话,为什么编译正常?
由于您指出的原因,程序格式错误。 编译器不是必需的诊断程序,但是在讨论格式错误的程序中导致崩溃的原因时,我没有任何意义。
不过,让我们做吧:
第一个示例可能不会崩溃,因为FooBar
的行为不会影响main
的运行。 该方法被调用,它执行某些操作,仅此而已。
在第二个示例中,您尝试返回Foo
。 FooBar
返回2.cpp
定义的Foo
版本。 main
在1.cpp
出现,因此它期望在1.cpp
定义的Foo
版本,这是完全不同的版本-不同的成员,大小。 您最有可能在析构函数上发生损坏。 (只是一个猜测)
6)程序中的类类型可以有多个定义,只要每个定义出现在不同的翻译单元中,并且这些定义满足以下要求。 [...]
- D的每个定义应由相同的令牌序列组成;
[...]
这是编译器/链接器的工作方式:
编译器转换具有提供的标头的cpp文件。 它生成一个.obj文件。 在您的情况下,o.bj文件将引用数据结构Foo
。 并且将没有任何其他细节。
链接器将.obj文件链接在一起。 它仅比较字符串名称。 在obj文件中,您具有相同的Foo
。 名称匹配。 对于链接器,这是同一件事。
之后,您开始程序。 它很可能会崩溃。 更具体地说,它将显示未定义的行为。 它可以进入无限循环,显示奇怪的消息等。
您有责任在cpp文件中为每个cpp文件的翻译提供相同的标题或定义。 现有的软件工具无法为您检查。 这就是它的工作方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.