I was really bothered by the inclusion of C stdlib functions on the global namespace and ended up writing things like ::snprintf or ::errno or struct ::stat, etc, to differentiate from some of my own functions in the enclosing namespace where those c stdlib functions were used.
Then I discovered that there is a way to declare every C stdlib function in the std namespace (as STL): just include < c(lib) > instead of < (lib).h > so I've edited my code the use those new "c for c++" includes.
On Debian/GCC 4.3.4 I had to 2 problems:
1) #error This file requires compiler and library support for the upcoming \
ISO C++ standard, C++0x. This support is currently experimental, and must be \
enabled with the -std=c++0x or -std=gnu++0x compiler options.
2) using -std=c++0x my program compiles just fine, but I have not modified ::snprintf or ::time, etc.. every C stdlib function is still on the global namespace =(! (no, I'm not using namespace std not even once)
Any thoughts?
For example.. how to stop the c stdlib from invading my global namespace? < c(lib) > is an experimental feature of the next C++ standard or could be used safely right now?
Then I've another doubt that perhaps deserves a new question.. there is no cmalloc. I know the whole history about new replacing malloc and why. but for simple plain byte buffers there is no c++ equivalent of realloc. I know that memory blocks and reallocation are implementation/so specific, but when there are contiguous free blocks of memory realloc works better than a new buffer allocation and memory copy.
Thanks =)!
For your first question, it depends on which headers you are trying to include. Most of the C headers are available in the c(lib) form in the existing version of C++. A few aren't, and may be added in C++0x. So if you tried to include any of those, you might have gotten that error.
Second, all the headers of this form guarantee that the functions will be made available in the std namespace. But they do not promise to leave the global namespace alone. Often, they put the symbols in both namespaces.
I'm not sure why ::snprintf bothers you more than std::snprintf though. You have to specify a prefix in both cases.
As for realloc, a C++ equivalent doesn't exist, probably because it's more trouble than it's worth, especially with C++'s more complicated semantics for copying objects. (In particular, if you try to use it, don't store any non-POD objects in the buffer, as realloc will just memcpy them to a newly allocated buffer if necessary, which will break non-POD objects.)
Of course, you can still use the old realloc from C by including its header. But I'd say you're probably better off using new/delete, and simply figuring out a sensible buffer allocation strategy.
The malloc() function, in standard C is not declared in the "<malloc.h>" header. It is declared in <stdlib.h>. Same for realloc() and free().
I don't know about C++, but instead of
#include <cmalloc>
try
#include <cstdlib>
c<lib>, which roughly encloses <lib>.h in a namespace std { }, is a standard feature of C++. See §17.4.1.2 if you have access to either standard.
This is not an experimental feature at all -- what header file is giving you the compatibility problems?
Using malloc et al. is fine, but be sure never to mix them with new/delete. (e.g. don't delete a malloc()'ed buffer.)
There are some of the standard C <lib.h> headers which are not yet transfered to <clib>. Probably you used <cstdint> or the like somewhere.
With the current standard you have the c libraries listed here. Note that <cstdint> is not part of it.
I didn't find a reference describing if and when <cstdint> will be part of c++, but if I try to include it, I also get an error message telling me I should use -std=c++0x, so I assume it is planned to be included in the next c++ standard.
Related
For example, i want to see the code of function toupper() to understand how it works, is there any way? I have searched and opened string.h library, but didn't find anything.
From a strict language point of view, you cannot "see the code" of a standard function, because the C++ language standard only defines functions' prototypes and behaviours, not how they are implemented.
In fact, from a strict language point of view, a standard function like toupper does not even have to have source code, because a standard header, like <string.h> does not even have to be a file!
Of course, in practice, you will probably never encounter a C++ implementation in which standard headers are not files, because files are just a natural and simple implementation of headers. This means that in practice, for the header <string.h>, there is actually a C++ source file called "string.h" somewhere on your computer. Just find it and open it.
I have searched and opened string.h library, but didn't find anything.
Then you have not looked close enough. Hint: This file most likely includes one or more other header files.
Note that if you actually looked for toupper, that function is not in <string.h> anyway. Look in <ctype.h> instead. cppreference.com is a good online reference to tell you which headers contain which functions.
http://en.cppreference.com/w/c/string/byte/toupper
Again, this does not mean that the corresponding header file of your compiler contains that function directly, but it may directly or indirectly include some other file which contains it.
In any case, beware of what you will see inside of your compiler's header files. It will usually be a lot more complicated than you may think, and, more importantly, it will often use constructs you are not allowed to use in your own code; after all, the code in those files is internal to the compiler implementation, and the compiler has a lot of privileges you don't have, for example using otherwise forbidden identifiers like _STD_BEGIN. Also expect a lot of completely non-standard #pragmas and other non-portable stuff.
Another important thing to keep in mind is that you are not supposed to dig through a function's implementation to find out what it does. In badly written software, i.e. software with confusing interfaces and no documentation (which exists everywhere in the real world), you unfortunately have to do this, provided you have access to the source code.
But C++ standard functions are perfectly documented and have, with some arguable exceptions, well-designed interfaces. It may be interesting, and educating, and sometimes even necessary for debugging, to look into their implementation on your system, but don't let this possibility keep you from learning two important software-engineering skills:
Reading documentation.
Programming to interfaces, not to implementations.
Yes, of course, you could (not all realizations, maybe). For example, the glibc implementation defines toupper function as:
#define __ctype_toupper \
((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128)
int
toupper (int c)
{
return c >= -128 && c < 256 ? __ctype_toupper[c] : c;
}
I have a C++ application running bare-metal that I want to make as small as possible.
I am not using dynamic memory allocation anywhere. I am using no STL functions. I've also overridden all the varieties of "delete" and "new" with empty functions. Nonetheless, when I look at a sorted list of symbols I see that malloc() is still one of the largest items in my compiled binary. I could shrink my binary by about 25% if I could get rid of it.
Do C++ runtimes generally require malloc() for behind-the-scenes type work?
(I'm using Xilinx's fork of gcc for the Microblaze architecture, if that matters)
Reliance of a program on malloc() can occur in both C and C++, even if the program doesn't directly use them. It is a quality of implementation matter for the compiler and standard library rather than a requirement by the standards.
This really depends on how the both the compiler startup code (code that sets things up so main() can be called) works and how standard library code is implemented.
In both C and C++, for example, startup code (in hosted environments) needs to collect information about command line arguments (possibly copy to some allocated buffer), connect to standard files/streams (like std::cout and std::cin in C++, and `stdout and stdin in C). Any of these things can involve dynamic memory allocation (e.g. for buffers associated with standard streams) or execute code that is not actually needed by the program.
C++ has two kinds of implementations, hosted and freestanding. Hosted implementations do assume that malloc is present and often do use it for internal purposes. Freestanding implementations assume that only the new function is present, because it supports the C++ keyword new, but it is easy to ensure that this function doesn't get called.
The difference between the two is that in a freestanding implementation, you can control program startup and the set of required headers and libraries is limited. Program startup is controlled by setting the entry point.
g++ -ffreestanding -e _entry program.cpp
program.cpp might be:
extern "C" int entry()
{
return 0;
}
The extern "C" is necessary to prevent C++ name mangling, which might make it difficult to figure out what the name of entry is during linking. Then, don't use new, std::string, stream I/O, STL, or the like, and avoid at_exit.
This should give you control over the startup and cleanup code and limit what the compiler can implicitly rely on being available from the standard library. Note, however, that this can be a challenging environment. Not only will you prevent initialization of heaps, I/O streams, and the like, but you will also prevent setup of exceptions, RTTI, and the calling of static storage object constructors, among other things. You will have to write code or use libraries to manually opt into several features of C++ you might want to use. If you go this route, you may want to peruse this wiki http://wiki.osdev.org/C%2B%2B. You may want to at least call global constructors, which is pretty easy to do.
Explanation
The standard
C++ has the notion of a "freestanding implementation", in which fewer headers are available.
3.6.1 Main function [basic.start.main]
1 [snip] It is implementation-defined whether a program in a freestanding environment is required to define a main function.
17.6.1.3 Freestanding implementations [compliance]
1 Two kinds of implementations are defined: hosted and freestanding (1.4). For a hosted implementation, this
International Standard describes the set of available headers.
2 A freestanding implementation has an implementation-defined set of headers. This set shall include at least
the headers shown in Table 16.
3 The supplied version of the header <cstdlib> shall declare at least the functions abort, atexit, at_quick_exit, exit, and quick_exit (18.5). [snip]
Table 16 lists ciso646, cstddef, cfloat, limits, climits, cstdint, cstdlib, new, typeinfo, exception, initializer_list, cstdalign, cstdarg, cstdbool, type_traits, and atomic.
Most of the above headers contain simple definitions of types, constants, and templates. The only ones that may seem problematic are typeinfo, exception, cstdlib, and new. The first two support RTTI and exceptions, respectively, which you can ensure are disabled with additional compiler flags. cstdlib and new you can simply ignore by not calling exit/at_exit and not using new expressions. The reason for avoiding at_exit is it might call new internally. Nothing else in the freestanding fragment should call call anything in cstdlib or new.
The options
The most important option above is -e _entry, which gives you control over what runs when your program starts.
-ffreestanding tells the compiler and the standard library (rather, its freestanding fragment) not to assume that the entire standard library is present (even if it still is). It may prevent the generation of surprising code. Note that this option doesn't actually restrict which headers are available to you. You can still use iostream, for instance, though it may be a bad idea if you also changed the entry point. What it does is it prevents the code supporting the freestanding headers from calling anything outside the freestanding headers, and prevents the compiler from generating any such calls implicitly.
If you use any STL like std::lib or std::map. Or even std::cout, there will be dynamic memory allocations behind the scene.
It will always need malloc. Because the binary has to be loaded and also the shared libraries.
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.
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).