![](/img/trans.png)
[英]Why does this std::function and operator cause a segmentation fault?
[英]Why does redeclaring std::cout cause a segmentation fault?
我正在用此代碼測試C ++。 我在Ubuntu 18.10上使用GCC版本8.3.0進行了編譯。
#include <ostream>
namespace std{
extern ostream cout;
};
int main(){
std::cout << "Hello world\n";
}
該代碼編譯沒有問題。 但是,執行時,程序將輸出:
分段故障(核心已轉儲)
這是為什么?
首先,我們已經介紹了您的程序具有未定義的行為,因為不允許您在這樣的命名空間std
聲明內容。 僅允許使用工具鏈。
通常,當您的程序具有UB時,例如讀取內存中的隨機部分或使優化器混亂,所有的賭注都消失了,我們甚至不用理會為什么我們看到某些特定結果。 但是,在這種情況下,它比這簡單一些。
例如,在libstdc ++ v3(您正在使用的版本)中,根據某些配置,出於版本控制的原因, 實際的流聲明 位於名稱空間std::__8
中,其中__8
是內聯名稱空間。 您的extern
聲明不是,所以它與真實的原始聲明不匹配。 這可能會導致鏈接器錯誤 ,因為新添加的聲明實際上不會與存在的任何對象結婚。
在其他配置中,聲明上可見性設置的沖突可能會使鏈接器進一步混淆,並在運行時導致分段錯誤。 真正確定原始聲明什么樣的唯一方法是在計算機上觀察程序#include <iostream>
的預處理源(這並不難;請使用g++ -E
!),然后看一下它最終針對您的特定配置。
這個故事的寓意是,盡管瀏覽cppreference.com會讓您相信cout
從簡單開始的:
namespace std {
ostream cout(/* some args */);
}
……現實通常更復雜,您的重新聲明沒有考慮任何復雜性,其中某些復雜性可能會違反規則,從而產生您觀察到的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.