Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A() = A() - why does it compile?

Tags:

c++

class A {};  int main() {  A() = A();  return 0;  } 

Why does this code compile? Shouldn't be there some error that on the left side of assignment operator should be placed lvalue? Is A() lvalue? g++ 4.7 version

like image 721
scdmb Avatar asked Apr 30 '13 15:04

scdmb


People also ask

What is the purpose of a compile?

Compilers analyze and convert source code written in languages such as Java, C++, C# or Swift. They're commonly used to generate machine code or bytecode that can be executed by the target host system.

Why does code need to be compiled?

Compiled languages are converted directly into machine code that the processor can execute. As a result, they tend to be faster and more efficient to execute than interpreted languages. They also give the developer more control over hardware aspects, like memory management and CPU usage.

Why we compile the program in C?

Compiling a C program:- Behind the Scenes. C is a mid-level language and it needs a compiler to convert it into an executable code so that the program can be run on our machine.

What is compiling in Python?

Compilation: The source code in python is saved as a . py file which is then compiled into a format known as byte code, byte code is then converted to machine code. After the compilation, the code is stored in . pyc files and is regenerated when the source is updated. This process is known as compilation.


2 Answers

For built-in types, you'd be correct: the built-in assignment operator requires a modifiable lvalue on the left hand side.

However, this is not using the built-in operator, but the overload that's implicitly declared by the class. This is a member function, equivalent to

A().operator=(A()); 

and member functions can be called on rvalues.

like image 178
Mike Seymour Avatar answered Oct 04 '22 05:10

Mike Seymour


If you really want, you can make it not compile with C++11:

class A {     template <typename T>     void operator=(T&&) && = delete; // no op= for rvalues      // generate other special members normally     A() = default;     A(A const&) = default;     A(A&&) = default;     ~A() = default;     // op= only for lvalues     A& operator=(A&&) & = default;     A& operator=(A const&) & = default; };  int main() {  A() = A(); // error  return 0;  } 

(live example)

Note the & and && (aka ref-qualifiers) at the end of the declarations of the various operator= forms. This makes those declarations be selected for lvalues and rvalues respectively. However, the rvalue version, when selected by overload resolution causes the program to be ill-formed because it is deleted.

The default generated operator=, however, does not have any ref-qualifier, meaning it can be called for both lvalues and rvalues; that's why the code in the question compiles, even though A() is an rvalue.

like image 37
R. Martinho Fernandes Avatar answered Oct 04 '22 05:10

R. Martinho Fernandes