The C++ Programming Language : Special Edition states on page 431 that...
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.
However, when I use C headers in the < cX > style, I don't need to qualify the namespace. For example...
#include <cmath>
void f() {
double var = sqrt( 17 );
}
This would compile fine. Even though the book says that using the < cX > header defines names in the std namespace only, you are allowed to use those names without qualifying the namespace. What am I missing here?
P.S. Using the GNU.GCC compiler
Stephan T. Lavavej, a member of the MSVC team, addresses the reality of this situation (and some of the refinements to the standard) in this comment on one of his blog postings (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
> also, <cstddef>, <cstdlib>, and std::size_t etc should be used!
I used to be very careful about that. C++98 had a splendid dream wherein <cfoo> would declare everything within namespace std, and <foo.h> would include <cfoo> and then drag everything into the global namespace with using-declarations. (This is D.5 [depr.c.headers].)
This was ignored by lots of implementers (some of which had very little control over the C Standard Library headers). So, C++0x has been changed to match reality. As of the N2723 Working Paper, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf , now <cfoo> is guaranteed to declare everything within namespace std, and may or may not declare things within the global namespace. <foo.h> is the opposite: it is guaranteed to declare everything within the global namespace, and may or may not declare things within namespace std.
In reality and in C++0x, including <cfoo> is no safeguard against everything getting declared in the global namespace anyways. That's why I'm ceasing to bother with <cfoo>.
This was Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .
(C++0x still deprecates the <foo.h> headers from the C Standard Library, which is hilarious.)
I'm in 100% agreement with Lavavej, except I never tried to be very careful about using the <cfoo> style headers even when I first started using C++ - the standard C ones were just too ingrained - and there was never any real world problem using them (and apparently there was never any real world benefit to using the <cfoo> style headers).
The rule for the C libraries differs from C++ libraries for namespaces
gcc interprets the standard in Gcc docs as
The standard specifies that if one includes the C-style header (<math.h> in this case), the symbols will be available in the global namespace and perhaps in namespace std:: (but this is no longer a firm requirement.) One the other hand, including the C++-style header (<cmath>) guarantees that the entities will be found in namespace std and perhaps in the global namespace.
In the draft C0X++ spec it says in section 17.6.2.3 Headers
It is unspecified whether these names are first declared within the global namespace scope and are then injected
into namespace std by explicit using-declarations
It's hard to fix this without implementing the C library twice. See DR 456, which basically proposes giving up on the problem.
Why do you say "This would compile fine" when it violates the Standard? Who allows you to use those names without qualifying the namespace? Have you tested this on a particular implementation and found that it works?
I strongly advise against using some particular non-standard feature because it happens to work on your compiler of choice. Such things break easily, perhaps with a later version of the same compiler.
You are probably missing using a standards-conformant compiler (or the one you use is configured to be compatible with pre-standard code).
Related
I'm a bit new to c++ and I have a coding assignment with a lot of files already done, but I noticed that VS2012 seems to have an issue with the following statement:
typedef std::uint32_t identifier;
However, it seems that changing it to
typedef uint32_t identifier;
gets rid of the error. There are no includes and this is in the header file. I noticed that the definition is in stdint.h. If that's the case, why is this code acceptable outside of VS (ie. compiles properly using g++) but is unacceptable in VS? Can anyone please explain this?
The difference is that one is inside a namespace and the other isn't. Otherwise they should be the same. The first is supposed to be the C version and the second is the C++ version. Before C++11 it was mandated that including the prefixed versions instead of the C standard library version brings in all C definitions inside the standard namespace. In C++11 this restriction has been relaxed as this is not always possible.
It could be that your compiler defines this type implicitly. In any case, you should include cstdint to make the version in the namespace std available (and possibly the one in the global namespace). Including stdint.h should just make the unqualified version available.
Earlier version of Visual Studio shipped without this header, so this is bound to be troublesome.
Due all this madness, most people will fall back on a third-party implementation such as boost/cstdint.hpp.
Edit: They are the same and serve the same purpose. As a rule: If you want to use the version in the std namespace, include cstdint. If you want the one in the global namespace, include stdint.h. For C++ it is recommended to use the one in the std namespace. As a rule: Always include what you use and don't rely on other headers including things for you.
uint32_t (aka ::uint32_t i.e. the one in the global namespace) is declared in <stdint.h>. That header might also declare it in namespace std, as std::uint32_t, but it's not required to do so.
std::uint32_t (i.e. the one in namespace std) is declared in <cstdint>. That header might also declare it in the global namespace, as ::uint32_t, but it's not required to do so.
If that's the case, why is this code acceptable outside of VS (ie. compiles properly using g++) but is unacceptable in VS? Can anyone please explain this?
If you want to use std::uint32_t then you must #include <cstdint>, or the code may not compile. If it does compile with G++ then presumably some other header indirectly includes <cstdint> but you shouldn't rely on that, include the right headers for the names you use.
In C++11 I can choose whether I want to use the types defined in with or without the namespace std::
At least my compiler (g++ 4.7) accepts both variants.
My question is: What is the recommended way to use the typedefs from cstdint. With or without the namespace? What are the advantages or disadvantages? Or is it only a matter of style?
so variant a):
#include <cstdint>
std::uint8_t n = 21;
resp:
#include <cstdint>
using std::uint8_t;
uint8_t n = 21;
or variant b):
#include <cstdint>
uint8_t n = 21;
Prefer names declared in the std namespace. The reason is given in §17.6.1.3/4 (ISO/IEC 14882:2011(E), C++11):
Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).
If you use the names from the <cname> headers without std, your program is relying on unspecified requirements.
This was different in C++03 and earlier where names were only supposed to appear in the std namespace. However, the reality was that many implementations were simply injecting the contents of the C standard library headers <name.h> into std and so this was accommodated for in C++11. The corresponding section (§17.4.1.2/4) from the C++03 standard says:
Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause 7), as appropriate, as if by inclusion. In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.
Further to this, qualifying names with std:: helps to avoid collisions - you know exactly what you're getting if you fully qualify it. If you're really going to do using namespace std or using std::something, at least do it in as minimal a scope as you can.
In C++11, for the C headers that are explicitly named in the C++ standard, the following holds:
An implementation is required for the <foo.h> versions to add them in the global namespace, and allowed to add them to the std:: namespace.
An implementation is required for the <cfoo> versions to add them in the std:: namespace, and allowed to add them to the global namespace.
The reason for wrapping things in the std namespace in the <cstdint> header is to avoid name collisions, which are quite unpleasant when they happen. However, in this case, it is very unlikely that the types will be found somewhere else. So I would use <stdint.h>, especially because this feature was introduced in C before it was added to C++, and hence the <stdint.h> header is older than <cstdint>, and therefore available in older compilers.
If you have decided that you want these names in the global namespace, you should also prefer <stdint.h> to <cstdint> followed by using namespace std, as the latter will dump all the other std stuff from other <cfoo> headers yhou have included into the global namspace too, which you probably do not want, as many other standard names are much more collision-prone than the likes of uint8_t.
Include <cstdint> and use std:: or include <stdint.h> to use unqualified type names. There are some platforms (e.g. QNX SDP 6.6) on which <cstdint> doesn't declare those types in the global namespace.
My personal style is to always fully qualify names so it is clear where they come from. That is, I would use std::uint8_t. That is, I would include <cstdint> and use qualified names.
That said, note that use of std::uint8_t is only indicated if you really mean to use a type with exactly 8 bits. If the platform you are running your code on doesn't have such a type, e.g., because it uses 9 bit units as its basic entity, the program is supposed not to compile. If you want to use the smallest unsigned with 8 bits available, you want to use uint_least8_t.
In what cases should we include cassert?
In short, don't use it; use <assert.h>.
C++11 removed any formal guarantee of a "c...." header not polluting the global namespace.
It was never an in-practice guarantee, and now it's not even a formal guarantee.
Hence, with C++11 there is no longer any conceivable advantage in using the "c...." header variants, while there is the distinct and clear disadvantage that code that works well with one compiler and version of that compiler, may fail to compile with another compiler or version, due to e.g. name collisions or different overload selection in the global namespace.
SO, while cassert was pretty meaningless in C++03 (you can't put a macro in a namespace), it is totally meaningless -- even as a special case of a general scheme -- in C++11.
Addendum, Dec 22 2013:
The standard defines each C++ C header <X.h> header in terms of the <cX> header, which in turn is defined in terms of the corresponding C library header.
C++11 §D.5/2:
“Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope.”
C++11 §D.5/3 (non-normative example):
“The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std.”
Stack Overflow user C.R.’s comment made me aware that some versions of g++, such as MinGW g++ 4.7.2, are quite non-standard with respect to the <X.h> headers, lacking the overloads of e.g. sin that the C++ standard requires:
I already knew that MinGW g++ 4.7.2 also entirely lacks functions such as swprintf, and that it has ditto shortcomings in the pure C++ library such as lacking C++11 std::to_string. However, the information about it lacking the C function overloads was new to me.
In practice the lacking overloads with g++ means
ignoring the g++ issue, or
avoiding using the missing g++ overloads,
e.g. using only double sin( double ), or
using the std namespace overloads
(one then needs to include <cmath> to guarantee their presence with g++).
In order to use the g++ std namespace overloads unqualified, one practical approach is to define headers wrappers for this compiler. I've used that approach to address g++ shortcomings wrt. to the printf family. For as David Wheeler once remarked, “All problems in computer science can be solved by another level of indirection”…
Then things can be arranged so that standard code that uses g++'s missing overloads, also compiles with g++. This adjusts the compiler to the standard, with a fixed amount of code.
Just like any other header file, you #include <cassert> when you use something declared in that header file, such as assert().
See an easily accessible reference
#include <iostream>
// uncomment to disable assert()
// #define NDEBUG
#include <cassert>
int main()
{
assert(2+2==4);
std::cout << "Execution continues past the first assert\n";
assert(2+2==5);
std::cout << "Execution continues past the second assert\n";
}
assert.h defines one macro function that can be used as a standard debugging tool.
So this is something that I've always wondered but was never quite sure about. So it is strictly a matter of curiosity, not a real problem.
As far as I understand, whenyou do something like #include <cstdlib> everything (except macros of course) are declared in the std:: namespace. Every implementation that I've ever seen does this by doing something like the following:
#include <stdlib.h>
namespace std {
using ::abort;
// etc....
}
Which of course has the effect of things being in both the global namespace and std. Is this behavior guaranteed? Or is it possible that an implementation could put these things in std but not in the global namespace? The only way I can think of to do that would be to have your libstdc++ implement every c function itself placing them in std directly instead of just including the existing libc headers (because there is no mechanism to remove something from a namespace). Which is of course a lot of effort with little to no benefit.
The essence of my question is, is the following program strictly conforming and guaranteed to work?
#include <cstdio>
int main() {
::printf("hello world\n");
}
EDIT: The closest I've found is this (17.4.1.2p4):
Except as noted in clauses 18 through
27, the contents of each header cname
shall be the same as that of the
corresponding header name.h, as
specified in ISO/IEC 9899:1990
Programming Languages C (Clause 7), or
ISO/IEC:1990 Programming Languages—C
AMENDMENT 1: C Integrity, (Clause 7),
as appropriate, as if by inclusion. In
the C + + Standard Library, however,
the declarations and definitions
(except for names which are defined as
macros in C) are within namespace
scope (3.3.5) of the namespace std.
which to be honest I could interpret either way. "the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C" tells me that they may be required in the global namespace, but "In the C + + Standard Library, however, the declarations and definitions (except for names
which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std." says they are in std (but doesn't specify any other scoped they are in).
Here's a nice synopsis of the situation (with some reality vs. what the standard says) from Stephan T. Lavavej of the MSVC team (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
> also, <cstddef>, <cstdlib>, and std::size_t etc should be used!
I used to be very careful about that. C++98 had a splendid dream wherein <cfoo> would declare everything within namespace std, and <foo.h> would include <cfoo> and then drag everything into the global namespace with using-declarations. (This is D.5 [depr.c.headers].)
This was ignored by lots of implementers (some of which had very little control over the C Standard Library headers). So, C++0x has been changed to match reality. As of the N2723 Working Paper, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf , now <cfoo> is guaranteed to declare everything within namespace std, and may or may not declare things within the global namespace. <foo.h> is the opposite: it is guaranteed to declare everything within the global namespace, and may or may not declare things within namespace std.
In reality and in C++0x, including <cfoo> is no safeguard against everything getting declared in the global namespace anyways. That's why I'm ceasing to bother with <cfoo>.
This was Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .
(C++0x still deprecates the <foo.h> headers from the C Standard Library, which is hilarious.)
I've never been fond of the <cfoo> headers myself, and found that I've always use <foo.h>. Now I feel like I can stop being anxious about my lack of C++ 'purity' in that regard.
At the present time, no. In fact, even though the code will work with every compiler I now of, it's really not supposed to work at all -- #includeing one of the c* headers is only supposed to give you access to the names inside of namespace std.
Since implementation of this was such a pain (getting it right essentially required duplicating the entire C library as a C++ library in the right namespace), in C++ 0x they've changed the requirements a bit -- your code is now allowed to work, though (at least if memory serves) it's still not required to work.
I cannot speak for the standards, as I have not read them, but one could envision a C++ environment that is not built on top of a C environment, or where the C environment is a compatibility layer on top of underlying C++ APIs. In such a case, these guarantees may not be made. I would be surprised if such an implementation would be prohibited from being a compliant implementation.
In standard library, I found that namespace std is declared as a macro.
#define _STD_BEGIN namespace std {
#define _STD_END }
Is this a best practice when using namespaces?
The macro is declared in Microsoft Visual Studio 9.0\VC\include\yvals.h. But I couldn't find the STL files including this. If it is not included, how it can be used?
Any thoughts..?
Probably not a best practice as it can be difficult to read compared to a vanilla namespace declaration. That said, remember rules don't always apply universally, and I'm sure there is some scenario where a macro might clean things up considerably.
"But I couldn't find the STL files including this. If it is not included, how it can be used?".
All files that use this macro include yvals.h somehow. For example <vector> includes <memory>, which includes <iterator>, which includes <xutility>, which includes <climits>, which includes <yvals.h>. The chain may be deep, but it does include it it some point.
And I want to clarify, this only applies to this particular implementation of the standard library; this is in no way standardized.
In general No. The macros were probably used at the time when namespaces were not implemented by some compilers, or for compatibity with specific platforms.
No idea. The file would probably be included by some other file that was included into the STL file.
One approach that I saw in a library that I recently used was:
BEGIN_NAMESPACE_XXX()
where XXX is the number of namespace levels for example:
BEGIN_NAMESPACE_3(ns1, ns1, ns3)
would take three arguments and expand to
namespace ns1 {
namespace ns2 {
namespace ns2 {
and a matching END_NAMESPACE_3 would expand to
}
}
}
(I have added the newlines and indentation for clarity's sake only)
I imagine the only reason to do this is if you want to make it easy to change the namespace used by your application / library, or disable namespaces altogether for compatibility reasons.
I could see doing this for the C libraries that are included in C++ by reference (eg., the header that C calls string.h and that C++ calls cstring). In that case, the macro definition would depend on an #ifdef _c_plus_plus.
I wouldn't do it in general. I can't think of any compiler worth using that doesn't support namespaces, exceptions, templates or other "modern" C++ features (modern is in quotes because these features were added in the mid to late '90s). In fact, by my definition, compilers are only worth using if they offer good support for their respective language. This isn't a language issue; it's a simple case of "if I chose language X, I'd prefer to use it as it exists today, not as it existed a decade or two ago." I've never understood why some projects spend time trying to support pre-ANSI C compilers, for instance.