slepasteur
slepasteur

Reputation: 186

nullptr_t not defined on g++ 4.9.2

I am using C++ Rest SDK on a project in linux comipled with g++ 4.9.2 with the -std=c++11 flag set.

Internaly C++ Rest SDK checks if nullptr exists like that:

#if defined nullptr_t
#define NEEDS_NULLPTR_DEFINED 0
#else
#define NEEDS_NULLPTR_DEFINED 1
#endif
#if NEEDS_NULLPTR_DEFINED
#define nullptr NULL
#endif

This check fail on my machine leading nullptr to be defined as NULL which breaks the compilation afterwards. I am not quite sure if g++ or C++ Rest SDK is to blame for that problem.

Do you have any idea on why this nullptr_t check fails with g++ 4.9.2 and how to fix it?

EDIT:

I submitted an issue to C++ REST SDK: https://casablanca.codeplex.com/workitem/340

Upvotes: 1

Views: 1169

Answers (2)

Barry
Barry

Reputation: 302922

I think you misunderstand what #ifdef tests for. Specifically

#if defined identifier

will (from §16.1, emphasis mine):

evaluate to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.

It only can check for if the identifier is defined by #define. But std::nullptr_t isn't a a macro name - it's a typedef. Specifically (§18.2/9):

nullptr_t is defined as follows:

namespace std {
    typedef decltype(nullptr) nullptr_t;
}

In a similar vein, the following program won't print anything:

int main() {
    #ifdef int
    std::cout << "int is defined" << std::endl;
    #endif
}

The test you want instead is:

#if __cplusplus >= 201103L
    // C++11
#else
    // not C++11
#endif

From the gcc docs:

__cplusplus
This macro is defined when the C++ compiler is in use. You can use __cplusplus to test whether a header is compiled by a C compiler or a C++ compiler. This macro is similar to __STDC_VERSION__, in that it expands to a version number. Depending on the language standard selected, the value of the macro is 199711L, as mandated by the 1998 C++ standard; 201103L, per the 2011 C++ standard; an unspecified value strictly larger than 201103L for the experimental languages enabled by -std=c++1y and -std=gnu++1y.

Upvotes: 7

SirGuy
SirGuy

Reputation: 10770

nullptr_t is not defined by the preprocessor, so having the preprocessor check for it won't work. nullptr is defined in g++-4.9.2 with -std=c++11, which a quick test program can verify.

    int main() {
      std::nullptr_t i = nullptr;
    }

Upvotes: 7

Related Questions