簡體   English   中英

為什么C ++編譯器默認情況下不對零,初始化整數,浮點和指針變量?

[英]Why don't C++ compilers zero-initialize integer, floating-point, and pointer variables by default?

有時,我們可以使用像valgrind這樣的工具來查明我們是否忘記初始化指針變量。 但是為什么現代編譯器不能讓我們擺脫這個難以重現的常見錯誤呢?

初始化並不總是令人滿意的:

  • 出於性能原因; 初始化內存需要時間,這可能不是必需的。 甚至有一些算法依賴於恆定時間分配來實現其所需的性能(初始化是線性時間)。 D認識到這一點,但有一種不同的(可能更好的)方法; 變量默認初始化,但具有特殊語法以防止初始化。

  • 有時沒有正確的默認值。 靜態分析或運行時調試功能可以幫助檢測何時使用變量而不進行初始化。 默認情況下,簡單地為它們分配一些(不正確的)值可能會隱藏使用這些值檢測到的錯誤。

您的問題有幾個方面。 首先,該標准並未強制要求這種行為。 但如果它不違反標准,它可能是可能的。 實際上,調試版本(例如在MSVC中)完全相反,並且初始化不是0而是具有一些魔術值 - 另一個魔術值用於填充“釋放”的內存。 同樣,這特定於調試版本,可以幫助檢測某些類型的錯誤,同時它可能隱藏其他錯誤或模糊代碼庫中的位置。

但我認為這里的性能問題更重要。 如果你要初始化整數和浮點數,為什么不在堆和堆棧上都有各種結構或數組呢? 這個問題當然是如果我編寫程序並分配一個緩沖區來讀取數據,如果我知道我要讀取x個字節並且緩沖區只有x,那么我為什么要浪費時間將緩沖區歸零呢?字節長?

我同意,依靠這種“隨機”行為就像在Debian SSH中發生的災難一樣不正確,但它表明人們依賴現有的行為並且這種行為的變化后果並不總是顯而易見的。

不完全是。 除了其他答案中提出的理由外,我想指出:

a) Global variables, static local variables are always initialized, if not explicitly, then implicitly zero.
b) For a custom class `class Test`, creating a new instance by `Test *ptr=new Test()` or `Test test;` gives an initialized object.

總而言之,最終在ELF文件的'.data''。bss'部分中的內容被顯式或隱式地初始化(零)。 原始類型中不包含在上述區域中的其他變量在顯式初始化之前具有未定義的內容(取決於您的編譯器)。 這是因為,ELF文件本身提供了一種以非常低的成本初始化a)類變量的方法,而在堆棧,堆等中初始化變量可能是一個可怕的開銷。

您可能會認為class Object可能在初始化時成本更高。 但是,最重要的是,省略原始類型的初始化是C中的工作原理,因此C ++符合它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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