2010-01-22 3 views
5

The C++ Programming Language: Special Edition Zustände auf Seite 431, dass ...Umfang C-Bibliotheken in 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.

Allerdings, wenn ich mit C-Header in dem < cX> Stil Ich muss den Namespace nicht qualifizieren. Zum Beispiel ...

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

Dies würde gut kompilieren. Auch wenn das Buch besagt, dass die Verwendung des cX> headersnur Namen im std-Namespace definiert, dürfen Sie diese Namen verwenden, ohne den Namespace zu qualifizieren. Was fehlt mir hier?

P.S. Verwenden des GNU.GCC-Compilers

+1

Was ist Ihr Compiler - viele Compiler entsprechen nicht genau – Mark

+0

Ich verwende den GNU.GCC Compiler – Anonymous

+0

Welche Version? 3.x ist zu alt IIRC. – MSalters

Antwort

9

Stephan T. Lavavej, ein Mitglied der MSVC-Team befasst sich mit der Realität dieser Situation (und einige der Verfeinerungen der Standard) in diesem Kommentar auf einem seiner Blog-Postings (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):

> auch, <cstddef>, <cstdlib>, und std::size_t usw. sollte verwendet werden!

Ich war damals sehr vorsichtig.C++ 98 hatte einen herrlichen Traum, wobei <cfoo> alles innerhalb des Namespace std deklarieren würde, und <foo.h> würde <cfoo> einschließen und dann alles mit using-declarations in den globalen Namespace ziehen. (Dies ist D.5 [depr.cheaders].)

Dies wurde von vielen Implementierern ignoriert (von denen einige sehr wenig Kontrolle über die Header der C Standard Library hatten). Also wurde C++ 0x geändert, um der Realität zu entsprechen. Ab dem N2723 Working Paper, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf, ist jetzt <cfoo> garantiert, alles innerhalb des Namespace std zu deklarieren und kann Dinge im globalen Namespace deklarieren oder nicht. <foo.h> ist das Gegenteil: Es ist garantiert, alles innerhalb des globalen Namespace zu deklarieren und Dinge innerhalb des Namespace std zu deklarieren oder nicht.

In Wirklichkeit und in C++ 0x, einschließlich <cfoo> ist kein Schutz gegen alles im globalen Namespace trotzdem deklariert werden. Deshalb höre ich auf, sich mit zu beschäftigen.

Dies war Bibliothek Ausgabe 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456.

(C++ 0x deprecates noch die <foo.h> Header aus dem C Standard Library, die urkomisch ist.)

ich mit Lavavej in Übereinstimmung von 100% bin, außer ich nie sehr vorsichtig sein, versuchte, über Ich benutze die <cfoo> Style-Header, auch als ich anfing, C++ zu benutzen - die Standard-C waren einfach zu tief verwurzelt - und es gab nie ein echtes Problem, sie zu verwenden (und anscheinend gab es nie einen wirklichen Weltvorteil für die Verwendung der <cfoo> Style-Header).

+0

So mit Style-Header sollte nicht die Portabilität schaden? – Anonymous

+0

Nein, '' Header sollten die Portabilität nicht beeinträchtigen. Sie sollten sich nicht darauf verlassen, dass die Namen dieser Header aus dem globalen Namespace ausgeschlossen werden. Denn in Wirklichkeit gibt es eine sehr gute Chance, dass sie sowieso dort sein werden. –

+8

Ich bin eine seltsame Art von Puristen und werde wahrscheinlich weiterhin die '' Header verwenden, aber das ist traurig zu wissen. – Omnifarious

0

Vermutlich fehlt Ihnen ein standardkonformer Compiler (oder der von Ihnen verwendete ist so konfiguriert, dass er mit vordefiniertem Code kompatibel ist).

1

Warum sagen Sie "Dies würde gut kompilieren", wenn es gegen den Standard verstößt? Wer darf diese Namen verwenden, ohne den Namespace zu qualifizieren? Haben Sie dies bei einer bestimmten Implementierung getestet und festgestellt, dass es funktioniert?

Ich rate dringend von der Verwendung bestimmter nicht-Standard-Funktion, weil es zufällig auf Ihren Compiler der Wahl funktioniert. Solche Dinge brechen leicht, vielleicht mit einer späteren Version desselben Compilers.

+0

+1 Works! = Soll funktionieren. –

6

Die Regel für die C-Bibliotheken von C unterscheidet ++ Bibliotheken für Namespaces

gcc interpretiert den Standard in Gcc docs als

Der Standard legt fest, dass, wenn man schließt die C-Stil-Header (< math.h > In diesem Fall sind die Symbole im globalen Namespace und vielleicht im Namespace std :: (aber das ist keine feste Voraussetzung mehr) verfügbar. Einerseits die C++ - style-Kopfzeile (<10 cmath>) garantiert dass die Entitäten in Namespace std und vielleicht im globalen Namespace gefunden werden.

Im Entwurf ++ C0x spec heißt es in Abschnitt 17.6.2.3 Headers

Es ist nicht spezifiziert, ob diese Namen im globalen Namensraum Umfang zuerst deklariert werden und dann in namespace std durch explizite injiziert mit -declarations

4

Es ist schwierig, dies zu beheben, ohne die C-Bibliothek zweimal zu implementieren. Siehe DR 456, die grundsätzlich vorschlägt, das Problem aufzugeben.

+0

+1 für die Verknüpfung mit dem DR. –