3

I perform following statements in MSVC with /std:c++17 successfully without any compile error.

class A {
 public:
  A() {
    std::cout << "default constructor." << std::endl;
  }
  A(const A&) {
    std::cout << "const A&" << std::endl;
  }
  A(A&&) {
    std::cout << "A&&" << std::endl;
  }
  int a;
};

A& a = A();
auto& b = A();

I can't believe that a lvalue reference can be initialized with a rvalue, as well as for auto&.

But I have tested with some online compiler and they issued compile error expectedly.

I really want to know what's the underlying reason of the distinction between MSVC with online compiler.

Any reply is very much appreciated!

1 Answers1

1

If you compile with the /Wall flag, you will be given the answer by the compiler itself:

warning C4239: nonstandard extension used: 'initializing': conversion from 'A' to 'A &'
note: A non-const reference may only be bound to an lvalue

warning C4239: nonstandard extension used: 'initializing': conversion from 'A' to 'A &'
note: A non-const reference may only be bound to an lvalue

I.e., the program is indeed ill-formed as per the C++17 standard, but leverages a MSVC non-standard extension. Note that your program is rejected for /std:latest, which arguably seems like a good decision on MSVC's side, as this is quite a dangerous extension.

DEMO.

dfrib
  • 70,367
  • 12
  • 127
  • 192