簡體   English   中英

為什么重新聲明std :: cout會導致分段錯誤?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM