Are there any predefined macros for C++ in order the code could identify the standard?
e.g. Currently most compilers puts "array" into "tr1" folder but for C++11 it would be part of STL. So currently
#include <tr1/array>
but c++11
#include <array>
What is the predefined macros for 03 standard and 11 standard in order I can use #ifdef to identify?
Also, I suppose there are macros for C90 and C99?
Thanksx
From Stroustrup's C++11 FAQ
In C++11 the macro __cplusplus will be set to a value that differs from (is greater than) the current 199711L.
You can likely test it's value to determine if it's c++0x or not then.
Nitpick...
Your particular issue does not depend on your compiler, it depends on the Standard Library implementation.
Since you are free to pick a different Standard Library that the one provided by your compiler (for example, trying out libc++ or stlport), no amount of compiler specific information will help you here.
Your best bet is therefore to create a specific header file yourself, in which you will choose either one or the other (depending on a build option).
// array.hpp
#ifdef STD_HAS_TR1_ARRAY_HEADER
#include <tr1/array>
#else
#include <array>
#endif
You then document the compiler option:
Passing -DSTD_HAS_TR1_ARRAY_HEADER will mean that std::tr1::array is defined in <tr1/array> instead of the default <array>.
And you're done.
From the draft N3242:
16.8 Predefined macro names [cpp.predefined]
...
The name _ _ cplusplus is defined to the value 201103L when
compiling a C++ translation unit. 155)
...
155) It is intended that future versions of this standard will
replace the value of this macro with a greater value.
Non-conforming compilers should use a value with at most five
decimal digits.
Ultimately, you're going to have to use compiler-specific information. At least, until C++0x becomes more widespreadly implemented. You basically need to pick driver versions that implement something and test compiler-specific macros on them.
The Boost.Config library has a number of macros that can help you.
Related
I am using GCC and my compiler defines those macros : __FLT_RADIX__, __FLT_MANT_DIG__, __FLT_MAX_EXP__, __FLT_HAS_INFINITY__, __FLT_HAS_QUIET_NAN__, __FLT_HAS_DENORM__, ... Are they specific to GCC or are they in the C++ standard ? I mean wether they are defined or not, I know their values are implementation-specific. If they are not in the standard, where can I find their equivalent for all compilers ?
Are they ... in the C++ standard ?
No.
Are they specific to GCC
They are not in GCC documentation, so they are not guaranteed to be in (future releases of) GCC either. They are for internal use (probably for portable implementation of the standard macros and std::numeric_limits).
where can I find their equivalent for all compilers ?
There are corresponding standard macros for most of these in the C standard library. Simply remove the underscores from beginning and end; for example FLT_RADIX. An exception is FLT_HAS_SUBNORM which is named differently as you can see. See the standard for full list of macros.
There are no standard macros for __FLT_HAS_QUIET_NAN__ or __FLT_HAS_INFINITY__. But the information (including the others) is in std::numeric_limits template.
I need to use those values in the preprocessor
It there a ways of using std::numiric_limits constants in the preprocessor
You could use metaprogramming. Write a program that generates a header file with custom macro definitions. Something like
std::cout << "#define MY_CUSTOM_FLT_HAS_QUIET_NAN "
<< std::numeric_limits<float>::has_quiet_NaN();
Then compile and run that meta program on the target system to generate the header to use to compile the main program.
According to C++ primer, <cstdlib> header defines NULL. cpluspplus says it is defined in <cstddef>.
Ultimately, if the right header is not included, I thought NULL can't be referenced.
From what i can see, however it can be referenced and produce programs and that compile and run without warnings or errors, after including only <iostream>
Please help me understand this.
The C standard requires that NULL be defined in locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h, and wchar.h.
The C++ standard requires that NULL be defined in the c* header corresponding to each of those.
The C standard is very strict about the names a standard can define--each standard header must define precisely the names the standard requires that header to define. The only other names it can define are those that are reserved for the implementation, such as those starting with an underscore followed by another underscore or a capital letter.
The C++ standard is much more permissive in this respect--including any one standard header can have the same effect as including any or all other standard headers.
From a practical viewpoint, C++ implementations used to take quite a bit of advantage of this permissiveness--that is, including one standard header frequently defined the names from a number of other standard headers. More recent implementations tend to work more like the C standard requires, staying much closer to each header defining only the names required by to be defined by that header. They're still probably not as strict about it as the C standard requires, but much closer than they used to be (as a rule).
C++03 section 18.1.2 says that NULL is defined in cstddef.
On some implementations, iostream may include cstddef, so including iostream would also give you NULL.
It is defined in <cstddef>
The C++11 standard section 18.2, table 30 explains what's in <cstddef> It says:
Table 30 — Header <cstddef> synopsis
Macros: NULL [...]
[...] The macro NULL is an implementation-defined C++ null pointer constant in this International Standard
The C++11 Standard says NULL must be defined in multiple files. They are:
<clocale>
<cstddef>
<cstdlib>
<cstring>
<ctime>
<cwchar>
This is mentioned in Table 149, Section C.3 C standard library/3 of the standard.
Here's an image of the table and some surrounding text.
In the latest version of MinGW (MinGW 5.3.0) NULL was defined in the wchar.h header as :
#define NULL 0
I've been looking over some code for a class and I see in one place it has this line:
#ifndef __SGI_STL_PORT
What is __SGI_STL_PORT ?
When will this be defined?
This is a "feature test macro"; it will be defined when using the STL port implementation of the standard template library (so, for example, if you include <vector> and it was provided by the STL port version of the library, then this macro will be defined). This can be useful for taking advantage of implementation-specific extensions which are not guaranteed to exist by the C++ standard.
Are all the functions in a conformant C++98/03/0x implementation completely C99 conformant?
I thought C++0x added some C99 (language) features, but never heard or read anything definitive about the C library functions.
Just to avoid any confusion, I'm talking about a C++ program using functions declared in the <c*> header set.
Thanks.
Most of the C99 standard library has been imported in C++0X but not all. From memory, in what wasn't imported there are
<ctgmath> simply includes <ccomplex> and <cmath>,
<ccomplex> behaves as if it included <complex>
<cmath> has quite a few adjustment (providing overload and template functions completing the C99 provided one)
Some other headers (<cstdbool>, <iso646.h>, ...) have adjustments to take differences between language into account (bool is primitive in C++, a macro provided by <stdbool.h> in C for instance), but nothing of the scope of the math part.
The headers <xxx.h> whose <cxx> form doesn't behaves as the C99 version simply declares the content of <cxxx> in the global namespace, they aren't nearer of the C99 <xxx.h> content.
A related thing: C++0X provides some headers in both cxxx and xxx.h forms which aren't defined in C99 (<cstdalign> and <cuchar>, the second one is defined in a C TR)
(I remembered that a bunch of mathematical functions from C99 had been put in TR1 but not kept in C++0X, I was mistaken, that bunch of mathematical functions weren't part of C99 in the first place).
No. C++03 is aligned with ANSI C89/ISO C90, not C99.
The upcoming C++0x standard is expected to be aligned to some degree with C99. See paragraph 17.6.1.2 in the current draft which lists ccomplex, cinttypes, cstdint etc. Note that, as AProgrammer mentions, some headers aren't exactly the same; further, that the header cuchar is aligned with the C Technical Report 19769 rather than C99.
What is the difference between <cstdint> and <tr1/cstdint>? (apart from that one puts things in namespace std:: and the other in std::tr1::)
Since this stuff isn't standard yet I guess it's compiler specific so I'm talking about gcc. To compile with the non-tr1 one I must compile with -std=c++0x, but there is no such restriction when using tr1.
Is the answer perhaps that there is none but you can't go around adding things to std:: unless there, well, standard. So until c++0x is standardised an error must be issued using <cstdint> but you dont need to worry when adding to the tr1:: namespace, which makes no claim to things in it being standard? Or is there more to this?
Thanks.
p.s - If you read "std" as standard, as I do, I do apologise for the overuse of the word in this Q.
At least as far as I know, there was no intent to change <cstdint> between TR1 and C++0x. There's no requirement for #includeing <cstdint> to result in an error though -- officially, it's nothing more or less than undefined behavior. An implementation is allowed to specify exact behavior, and in this case it does.
I think you've got it. On my system, they're very similar, but with different macro logic. For instance, /usr/include/c++/4.4/tr1/cstdint has:
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 tr1::
but /usr/include/c++/4.4/cstdint has:
# define _GLIBCXX_BEGIN_NAMESPACE_TR1
# define _GLIBCXX_END_NAMESPACE_TR1
# define _GLIBCXX_TR1
So if it's being included as <cstdint> the TR1 namespace is simply defined into oblivion.
<tr1/cstdint> is defined, as name suggests, in TR1, while <cstdint> is defined in c++0x.
From gcc manual, -std=c++0x is needed to enable experimental features that are likely to be included in C++0x. However, <tr1/cstdint> is defined in TR1, not c++0x, so -std=c++0x is no needed.
The following is gcc manual for -std=c++0x for your reference.
The working draft of the upcoming ISO C++0x standard. This
option enables experimental features that are likely to be
included in C++0x. The working draft is constantly changing,
and any feature that is enabled by this flag may be removed
from future versions of GCC if it is not part of the C++0x
standard.