2014-09-05 77 views
18

考慮以下幾點:從空緩衝區構造一個`std :: ostream`有效嗎?

std::ostream out(nullptr); 

這是法律和明確定義的?


怎麼樣,如果我現在做的事:

out << "hello world\n"; 

這是法律和明確定義的?如果是這樣,大概它是沒有任何操作?

+0

我總是添加一個單元測試,如果我覺得這樣的事情應該工作,似乎是有效的。這樣,如果有人爲另一個編譯器/平臺構建stdlib,那麼他們知道它已經損壞。 – paulm 2014-09-05 16:59:36

+2

@paulm:我幾乎同意,除了單元測試不是用來驗證明確定義的東西。 – 2014-09-05 17:09:04

+0

除非它訪問內存越界或什麼我沒有看到問題?但是,然後單元測試應該運行應用程序驗證啓用/ valgrind等 – paulm 2014-09-05 17:17:37

回答

22

是的,它是合法的,定義良好的實例化該流。您可以安全地將其與另一個流交換,或者在稍後給它一個新指針(此時指向一個現存的緩衝區)。輸出操作本身確實是沒有操作的。

這裏的原因:

  1. 建設沒有非空前提,只有這個後置條件:

    [C++11: 27.7.3.2/2]:後置條件:rdbuf() == sb

  2. 有趣的是,它使沒有操作應sb在構造函數中進行明確一點:

    [C++11: 27.7.3.2/4]:備註:不上rdbuf()執行任何操作。

  3. 但說明還:

    [C++11: 27.7.3.2/1]:效果:構造basic_ostream類的一個對象,通過調用basic_ios<charT,traits>::init(sb)(27.5.5.2)分配給所述基類的初始值。

  4. init(sb)呼叫對流設定badbit的效果時sb是NULL:

    [C++11: 27.5.5.2/3]:後續條件:本函數的後置條件在表128

    [C++11: Table 128]:被指示[...]rdstate()goodbit if sb不是空指針,否則爲 badbit[..]

  5. 輸出操作結果在動作相當於解引用一個空指針:成員函數簽名

    [C++11: 27.7.3.1/2]:兩組共享公共屬性:格式化輸出函數(或插入器)和未格式化的輸出功能。 這兩組輸出函數都通過相當於調用rdbuf()->sputc(int_type)的操作來生成(或插入)輸出字符。overflow(),xsputn()sync()之外,他們可以使用basic_ostream的其他公共成員,除非他們不應調用rdbuf()的任何虛擬成員。

    但它從來沒有得到這一步,因爲basic_ostream::sentry建設:

    [C++11: 27.7.3.4/3]:如果任何準備完成後,os.good()trueok_ == true否則,ok_ == false

    ,併爲explicit operator basic_ostream::sentry::bool() const;

    [C++11: 27.7.3.4/5]:效果:返回ok_

    和:

    [C++11: 27.7.3.7/1]:每個無格式輸出功能通過構建sentry類的對象開始執行。如果此對象返回true,同時轉換爲bool類型的值,則該函數將盡力生成請求的輸出。 [..]

    &hellip;其含義是,沒有輸出操作發生在所有時badbit已經設置。

This was also the case in C++03.

+1

+1 Cooool的東西!很高興知道,如何通過使用'std :: ostream'來有效地創建'/ dev/null'。 – 2014-09-05 17:12:20

相關問題