为什么重新声明std :: cout会导致分段错误?

时间:2019-07-13 15:57:45

标签: c++ linux g++

我正在用此代码测试C ++。我在Ubuntu 18.10上使用GCC版本8.3.0编译。

Below code did the job for me

HTML File:
----------
<p class="section-header">Details</p><hr>

CSS File:
----------
.section-header{
    float: left; 
    font-weight: bold
}

hr{
    float: left;
    width: 80%;
}

INLINE:
-------
<p style="float: left;font-weight: bold">Details</p><hr style="float: left;width: 80%;">

代码被编译没有问题。但是,执行时,程序会打印出:

  

分段错误(核心已转储)

那是为什么?

1 个答案:

答案 0 :(得分:3)

首先,我们已经介绍了您的程序具有未定义的行为,因为不允许您这样声明名称空间std中的内容。仅允许使用工具链。

通常,当您的程序具有UB时,例如读取内存中的随机部分或使优化器混乱,所有的赌注都消失了,我们甚至不必费心尝试为什么,我们看到了一些特殊之处结果。但是,在这种情况下,它比这要简单一些。

例如,在libstdc ++ v3(您正在使用的版本)中,出于版本控制的原因,取决于某些配置,the actual stream declarationsin namespace std::__8,其中__8是内联命名空间。您的extern声明不正确,因此与真实的原始声明不匹配。这可能会导致a linker error,因为新添加的声明实际上不会与任何存在的对象结婚。

在其他配置中,声明上的conflicting visibility settings可能会使链接器更加混乱,并在运行时导致分段错误。 真正确定原始声明看起来像的唯一方法是在计算机上观察程序#include <iostream>的预处理源(这并不难;使用g++ -E!),然后看看它最终如何适合您的特定配置。

这个故事的寓意是,尽管浏览cppreference.com会让您相信cout是从简单开始的:

namespace std {
   ostream cout(/* some args */);
}

…现实通常更加复杂,您的重新声明没有考虑任何复杂性,并且其中某些复杂性可能会违反规则,从而产生您观察到的结果。