4

I saw this kind of cast for the first time today, and I'm curious as to why this works. I thought casting in this manner would assign to the temporary, and not the class member. Using VC2010.

class A
{
public:

   A() :
      m_value(1.f)
   {
      ((float)m_value) = 10.f;
   }

   const float m_value;
};
nvoigt
  • 75,013
  • 26
  • 93
  • 142
Hanoixan
  • 449
  • 3
  • 12
  • 2
    Is that the exact snippet you tried? Normally this should error out because m_value is not initialized and should not compile the assignment. – PlasmaHH Mar 11 '13 at 16:12
  • http://liveworkspace.org/code/nVBzK$0, apparently it doesn't work – Tony The Lion Mar 11 '13 at 16:12
  • 4
    That **is not** allowed, and it should error out for multiple reasons (including the fact that `m_value` is not assigned a value in the initialization list) – David Rodríguez - dribeas Mar 11 '13 at 16:13
  • Before your question, Didn't you need to initialize that `m_value` at A's constructor? – masoud Mar 11 '13 at 16:14
  • I edited to be what I actually used. It still assigns it. Glad to know my suspicions were correct. – Hanoixan Mar 11 '13 at 16:25
  • I believe that's a GCC extension. It does not work under Clang. See [C/C++ Language Compatibility, lvalue cast](http://clang.llvm.org/compatibility.html#lvalue-cast) – jww Aug 02 '15 at 04:08

2 Answers2

5

Even after fixing all other problems to make the code compile, it only works in VC2010 because it uses a non-standard extension. And If you specify /Wall to see all warnings, you compiler will emit

warning C4213: nonstandard extension used : cast on l-value

nvoigt
  • 75,013
  • 26
  • 93
  • 142
4

It shouldn't work. An explicit type conversion to float with cast notation will be a prvalue (§5.4):

The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.

My emphasis added.

The assignment operator requires an lvalue as its left operand (§5.17):

All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.

A prvalue is not an lvalue.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324