So, I find myself in the need of libc in my C++ program. However, I do not like the idea of sprinkling it all over the global namespace. Ideally, I'd like to force the entirety of libc into the std:: namespace so I'd have to do std::memcpy rather than memcpy.
Is this possible? And how? I'm willing to use compiler-specific macros if needed (I target only MS VC++ 10.0 and GCC 4.6).
Edit: I do literally mean 'force the declarations into std' - so that they are uncallable without the std:: prefix. Also, I am including cstdio, not stdio.h.
Thanks!
You cannot do this, unless it's already done.
The namespace std is reserved to the Standard Library, it is forbidden to add new members to this namespace. Therefore, if the C-headers are not already embedded within std, then you have no choice but to accept it.
On the other hand, you can perfectly create a new namespace, cstd, and bring the symbols from the global namespace in it with using directives... but it won't make them disappear from the global namespace.
I do literally mean 'force the declarations into std' - so that they are uncallable without the std:: prefix.
You can't do this if your implementation exposes the names in the global namespace. You can use the <cXXX> headers and then use std:: yourself.
This is, perhaps, unfortunate, but it is a consequence of C compatibility, since C does not understand namespaces. C++ has traditionally maintained many kludges and sacrifices for C compatibility.
Make wrapper includes
//stdlib.hpp
namespace std
{
#include <stdlib.h> //edit: changed from cstdlib to stdlib.h
}
If the linker hates this try just declaring the functions you want:
namespace std{ extern "C" {
int memcpy( void *out, const void *in);
} }
The reason some (most?) C++ compilers have the C functions in the global namespace, is simply that they have to use the existing operating system functions. For example, the file functions might not be a separate C library, but the file handling of the OS.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it a good idea to wrap an #include in a namespace block?
I've got a project with a class log in the global namespace (::log).
So, naturally, after #include <cmath>, the compiler gives an error message each time I try to instantiate an object of my log class, because <cmath> pollutes the global namespace with lots of three-letter methods, one of them being the logarithm function log().
So there are three possible solutions, each having their unique ugly side-effects.
Move the log class to it's own namespace and always access it with it's fully qualified name. I really want to avoid this because the logger should be as convenient as possible to use.
Write a mathwrapper.cpp file which is the only file in the project that includes <cmath>, and makes all the required <cmath> functions available through wrappers in a namespace math. I don't want to use this approach because I have to write a wrapper for every single required math function, and it would add additional call penalty (cancelled out partially by the -flto compiler flag)
The solution I'm currently considering:
Replace
#include <cmath>
by
namespace math {
#include "math.h"
}
and then calculating the logarithm function via math::log().
I have tried it out and it does, indeed, compile, link and run as expected. It does, however, have multiple downsides:
It's (obviously) impossible to use <cmath>, because the <cmath> code accesses the functions by their fully qualified names, and it's deprecated to use in C++.
I've got a really, really bad feeling about it, like I'm gonna get attacked and eaten alive by raptors.
So my question is:
Is there any recommendation/convention/etc that forbid putting include directives in namespaces?
Could anything go wrong with
diferent C standard library implementations (I use glibc),
different compilers (I use g++ 4.7, -std=c++11),
linking?
Have you ever tried doing this?
Are there any alternate ways to banish the math functions from the global namespace?
I've found several similar questions on stackoverflow, but most were about including other C++ headers, which obviously is a bad idea, and those that weren't made contradictory statements about linking behaviour for C libraries. Also, would it be beneficial to additionally put the #include <math.h> inside extern "C" {}?
edit
So I decided to do what probably everyone else is doing, and put all of my code in a project namespace, and to access the logger with it's fully qualified name when including <cmath>.
No, the solution that you are considering is not allowed. In practice what it means is that you are changing the meaning of the header file. You are changing all of its declarations to declare differently named functions.
These altered declarations won't match the actual names of the standard library functions so, at link time, none of the standard library functions will resolve calls to the functions declared by the altered declarations unless they happen to have been declared extern "C" which is allowed - but not recommended - for names which come from the C standard library.
ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] applies to the C standard library headers as they are part of the C++ standard library:
A translation unit shall include a header only outside of any external declaration or definition[*], and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.
[*] which would include a namespace definition.
Why not putting a log class in it's own namespace and using typedef namespace::log logger; to avoid name clashes in a more convenient way?
Change your class's name. Not that big of a deal. ;-)
Seriously though, it's not a great idea to put names in the global namespace that collide with names from any standard header. C++03 didn't explicitly permit <cmath> to define ::log. But implementations were chronically non-conforming about that due to the practicalities of defining <cmath> on top of an existing <math.h> (and perhaps also an existing static-link library for some headers, including math). So C++11 ratifies existing practice, and allows <cmath> to dump everything into the global namespace. C++11 also reserves all those names for use with extern "C" linkage, and all function signatures for use with C++ linkage, even if you don't include the header. But more on that later.
Because in C++ any standard header is allowed to define the names from any other standard header (i.e, they're allowed to include each other), this means that any standard header at all can define ::log. So don't use it.
The answer to your question about different implementations is that even if your scheme works to begin with (which isn't guaranteed), in some other implementation there might be a header that you use (or want to use in future in the same TU as your log class), that includes <cmath>, and that you didn't give the namespace math treatment to. Off the top of my head, <random> seems to me a candidate. It provides a whole bunch of continuous random number distributions that plausibly could be implemented inline with math functions.
I suggest Log, but then I like capitalized class names. Partly because they're always distinct from standard types and functions.
Another possibility is to define your class as before and use struct log in place of log. This doesn't clash with the function, for reasons that only become clear if you spend way too much time with the C and C++ standards (you only use log as a class name, not as a function and not as a name with "C" linkage, so you don't infringe on the reserved name. Despite all appearances to the contrary, class names in C++ still inhabit a parallel universe from other names, rather like struct tags do in C).
Unfortunately struct log isn't a simple-type-identifier, so for example you can't create a temporary with struct log(VERY_VERBOSE, TO_FILE). To define a simple-type-identifier:
typedef struct log Log;
Log(VERY_VERBOSE, TO_FILE); // unused temporary object
An example of what I say in a comment below, based on a stated example usage. I think this is valid, but I'm not certain:
#include <iostream>
#include <cmath>
using std::log; // to enforce roughly what the compiler does anyway
enum Foo {
foo, bar
};
std::ostream &log(Foo f) { return std::cout; }
int main() {
log(foo) << log(10) << "\n";
}
It is ugly hack too, but I believe will not cause any linker problems. Just redefine log name from <math.h>
#define log math_log
#include <math.h>
#undef log
It could cause problems with inline functions from math using this log, but maybe you'd be lucky...
Math log() is still accessible but it's not easy. Within functions where you want to use it, just repeat its real declaration:
int somefunc() {
double log(double); // not sure if correct
return log(1.1);
}
I'm writing a library to use in my projects. In it, I was hoping to wrap the c standard library in my library's namespace and a cstd namespace to avoid having its functions in the global namespace. However, from a previous question I asked and from what I've tested, I can't just #include everything in a namespace. Is there any way to do this?
I doubt it, unless you wanted to rewrite everything.
The C language itself has no concept of namespaces, so everything the C standard library uses must rely on the fact that whatever it is looking for resides in the global namespace.
If you simply wrapped a namespace around your #includes, the compiler wouldn't be able to find anything because it wouldn't know what namespace to look in.
The usual approach would be to put the 3rd party includes in the implementation files to keep them from polluting your api.
myapi.hpp
void coolthing( int howcool );
myapi.cpp
#include <coollib.h>
void coolthing( int howcool )
{
coollib_coolthing( howcool );
}
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.
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).