2010-01-22 43 views
5

的C++編程語言:在431頁的特別版狀態...範圍在C C庫++的 - <X.h> VS <cX>

For every header <X.h> defining part of the C standard library in the global namespace and also in namespace std, there is a header <cX> defining the same names in the std namespace only.

然而,當我使用C頭文件在< CX>風格,我不需要限定命名空間。例如...

#include <cmath> 
void f() { 
    double var = sqrt(17); 
} 

這將編譯得很好。儘管本書說使用< cX>頭文件僅在std名稱空間中定義名稱,但您可以使用這些名稱而不必限定名稱空間。我在這裏錯過了什麼?

P.S.使用GNU.GCC編譯器

+1

什麼是您的編譯器 - 許多編譯器不完全符合 – Mark

+0

我正在使用GNU.GCC編譯器 – Anonymous

+0

哪個版本? 3.x太老IIRC了。 – MSalters

回答

9

斯蒂芬T. Lavavej,MSVC的團隊的一員,解決這種情況的現實(和一些改進的標準)在他的博客的一個帖子此評論(http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):

><cstddef>,<cstdlib>std::size_t等也應該使用!

我曾經對此非常小心。C++ 98有一個輝煌的夢想,其中<cfoo>將聲明名稱空間標準內的所有內容,並且<foo.h>將包括<cfoo>,然後使用using聲明將所有內容拖入全局名稱空間。 (這是D.5 [depr.c.headers])。

很多實現者(其中一些對C標準庫頭文件的控制很少)忽略了這一點。所以,C++ 0x已經改變爲符合現實。至於N2723工作文件,http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf,現在的<cfoo>保證聲明名稱空間標準內的所有內容,並且可能或不可以在全局名稱空間內聲明內容。 <foo.h>則相反:它保證聲明全局名稱空間中的所有內容,並且可能會或可能不會在名稱空間std中聲明所有內容。

實際上,在C++ 0x中,包括<cfoo>都無法防止在全局名稱空間中聲明的所有內容。這就是爲什麼我不再打擾<cfoo>

這是圖書館問題456,http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456

(C++ 0x中仍然不贊成從C標準庫,這是熱鬧的<foo.h>頭。)

我與Lavavej 100%的協議,但我從來沒有試圖要非常小心使用<cfoo>風格頭文件,即使當我第一次使用C++時 - 標準的C頭文件根本就是根深蒂固的 - 並且從來沒有使用過它們的真實世界問題(顯然使用<cfoo>樣式頭文件從未有任何實際的好處)。

+0

那麼使用風格的標題不應該傷害可移植性? – Anonymous

+0

不,使用''標頭不應該傷害可移植性。你不應該指望從全局命名空間中排除的頭部名稱。因爲實際上他們很可能會在那裏。 –

+8

我是一個奇怪的純粹主義者,可能會繼續使用''標題,但這很難令人知道。 – Omnifarious

0

您可能會錯過使用符合標準的編譯器(或者您使用的編譯器配置爲與預標準代碼兼容)。

1

爲什麼在違反標準時會說「這樣會編好」?誰允許您使用這些名稱而不限定名稱空間?你有沒有在特定的實現上測試過它,發現它有效?

我強烈建議不要使用某些特定的非標準功能,因爲它恰好適用於您選擇的編譯器。這種情況很容易破壞,可能是使用相同編譯器的更高版本。

+0

+1 Works!=應該有效。 –

6

對於C程序庫的規則從C++對名稱空間庫不同

GCC解釋爲

Gcc docs標準的標準規定,如果一個包括C風格頭(< math.h中>在這種情況下),這些符號將在全局命名空間中可用,也許在命名空間std ::中(但這不再是一個堅定的要求)。另一方面,包括C++風格的頭文件(< cmath>)保證這些實體可以在名稱空間std中找到,也可以在全局名稱空間中找到。

在草案C0X ++符合規範它說,在第17.6.2.3頭

它是不確定是否這些名稱是全局命名空間範圍內的第一個聲明,然後用注射 到空間std通過明確 - 聲明

4

很難解決這個問題,如果不實施C庫兩次。見DR 456,基本上建議放棄這個問題。

+0

+1用於鏈接到DR。 –