3

I have this code:

const float foo = 5.0F;

static_assert(foo > 0.0F, "foo must be greater than 0.");

But in I get the error:

error C2057: expected constant expression

I'm actually doing this correctly and just hasn't properly implemented static_assert, right? In it works as intended.


There has been some commentary of the differences between const and constexpr. I understand this difference, however many compilers support this use of static_assert so I'll ask again, is this legal code or not? I'm not as concerned about which compiler supports it, I'm concerned about whether it's defined under the C++ standard.

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • `static_assert` requires C+11 see: http://en.cppreference.com/w/cpp/language/static_assert You would need to update your compiler to use this. – Richard Critten Oct 26 '17 at 18:51
  • @RichardCritten Visual Studio 2010 supported it: https://msdn.microsoft.com/en-us/library/dd293588(v=vs.100).aspx – Jonathan Mee Oct 26 '17 at 18:52
  • Possible duplicate of [const vs constexpr on variables](https://stackoverflow.com/questions/13346879/const-vs-constexpr-on-variables) – Amadeus Oct 26 '17 at 18:53
  • Voting to close. In you particular problem, is that a const can be initialized on runtime, while constexpr should be initialized at compile time – Amadeus Oct 26 '17 at 18:55
  • @Amadeus There needs to be a ruling on this for constant global variables, can they or can they not be `static_asserted`, the question you link does not answer that question. This is not a duplicate. – Jonathan Mee Oct 26 '17 at 19:21

1 Answers1

3

foo > 0.0F is not a core constant expression:

  1. An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:

...

(2.7) an lvalue-to-rvalue conversion unless it is applied to

(2.7.1) a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression, or

(2.7.2) a non-volatile glvalue that refers to a subobject of a string literal, or

(2.7.3) a non-volatile glvalue that refers to a non-volatile object defined with constexpr, or that refers to a non-mutable subobject of such an object, or

(2.7.4) a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;

foo is of floating-point type, for foo > 0.0F an lvalue-to-rvalue conversion on foo is required, which doesn't match the above conditions, then foo > 0.0F is not considered as constant expression:

A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints

On the other hand, if declare foo as integral type the code would be fine. LIVE (Usingconstexpr instead of const works too. LIVE)

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • So I appreciate the comment, and it must have some merit cause I do see 2.7.1 here. But why does a comparison on `foo` require an lvalue-to-rvalue conversion? Seems like I'm comparing an lvalue to primitive literal. – Jonathan Mee Oct 27 '17 at 12:59
  • 1
    @JonathanMee Difficult question. From [this answer](https://stackoverflow.com/a/20999389/3309790), "we need the lvalue-to-rvalue conversion to access the value inside an object", so lvalue-to-rvalue conversion is required to extract the value of `foo` for comparing. More precisely, `operator>` expects its operand as a prvalue. BTW if you use literal directly code will [compile](https://wandbox.org/permlink/nIZX4aMSDSjcDGWy), lvalue-to-rvalue conversion is not required at all. – songyuanyao Oct 27 '17 at 14:39
  • I have had a hard time finding explicit clarification that a floating point comparison invokes an lvalue to rvalue comparison. Given your standard quote it seems fairly certain that this does happen, but I'd still like explicit clarification before accepting this answer. Question is here: https://stackoverflow.com/q/46980595/2642059 – Jonathan Mee Oct 27 '17 at 17:44