c++ - constexpr and initialization of a static const void pointer with reinterpret cast, which compiler is right? -



c++ - constexpr and initialization of a static const void pointer with reinterpret cast, which compiler is right? -

consider next piece of code:

struct foo { static constexpr const void* ptr = reinterpret_cast<const void*>(0x1); }; auto main() -> int { homecoming 0; }

the above illustration compiles fine in g++ v4.9 (live demo), while fails compile in clang v3.4 (live demo) , generates next error:

error: constexpr variable 'ptr' must initialized constant expression

questions:

which of 2 compilers right according standard?

what's proper way of declaring look of such kind?

tl;dr

clang correct, known gcc bug. can either utilize intptr_t instead , cast when need utilize value or if not workable both gcc , clang back upwards little documented work-around should allow particular utilize case.

details

so clang right on 1 if go draft c++11 standard section 5.19 constant expressions paragraph 2 says:

a conditional-expression core constant look unless involves 1 of next potentially evaluated subexpression [...]

and includes next bullet:

— reinterpret_cast (5.2.10);

one simple solution utilize intptr_t:

static constexpr intptr_t ptr = 0x1;

and cast later on when need utilize it:

reinterpret_cast<void*>(foo::ptr) ;

it may tempting leave @ story gets more interesting though. know , still open gcc bug see bug 49171: [c++0x][constexpr] constant expressions back upwards reinterpret_cast. clear give-and-take gcc devs have clear utilize cases this:

i believe found conforming usage of reinterpret_cast in constant expressions useable in c++03:

//---------------- struct x { x* operator&(); }; x x[2]; const bool p = (reinterpret_cast<x*>(&reinterpret_cast<char&>(x[1])) - reinterpret_cast<x*>(&reinterpret_cast<char&>(x[0]))) == sizeof(x); enum e { e = p }; // e should have value equal 1 //----------------

basically programme demonstrates technique, c++11 library function addressof based on , excluding reinterpret_cast unconditionally constant expressions in core language render useful programme invalid , create impossible declare addressof constexpr function.

but not able exception carved these utilize cases, see closed issues 1384:

although reinterpret_cast permitted in address constant expressions in c++03, restriction has been implemented in compilers , has not proved break important amounts of code. cwg deemed complications of dealing pointers tpes changed (pointer arithmetic , dereference not permitted on such pointers) outweighed possible utility of relaxing current restriction.

but apparently gcc , clang back upwards little documented extension allows constant folding of non-constant expressions using __builtin_constant_p (exp) , next expressions accepted both gcc , clang:

static constexpr const void* ptr = __builtin_constant_p( reinterpret_cast<const void*>(0x1) ) ? reinterpret_cast<const void*>(0x1) : reinterpret_cast<const void*>(0x1) ;

finding documentation near impossible llvm commit informative next snippets provide interesting reading:

support gcc __builtin_constant_p() ? ... : ... folding hack in c++11

and:

+// __builtin_constant_p ? : magical, , potential constant.

and:

// macro forces argument constant-folded, if it's not // otherwise constant expression. define fold(x) (__builtin_constant_p(x) ? (x) : (x))

we can find more formal explanation of feature in gcc-patches email: c constant expressions, vlas etc. fixes says:

furthermore, rules __builtin_constant_p calls conditional look status in implementation more relaxed in formal model: selected half of conditional look folded without regard whether formally constant expression, since __builtin_constant_p tests folded argument itself.

c++ gcc c++11 clang constexpr

Comments

Popular posts from this blog

php - Android app custom user registration and login with cookie using facebook sdk -

django - Access session in user model .save() -

php - .htaccess Multiple Rewrite Rules / Prioritizing -