DEV Community

Karan Hejmadi
Karan Hejmadi

Posted on

2 2

Understanding lvalues and rvalues in C++

If you have worked with C++, you might've come across errors like "Expression must be a modifiable lvalue". This post will give you a clear understanding on what those terms mean.

In simple terms, lvalue is something that has a memory address and rvalue doesn't.

An easy example.

int a = 10;
Enter fullscreen mode Exit fullscreen mode

Here, 10 is rvalue and a is lvalue. Simply because 10 does not have any location. It is just a temporary constant which the compiler creates to assign it to a;

Key points to note

  • An rvalue cannot be assigned any value
int a;
10 = a; // NOT VALID!
Enter fullscreen mode Exit fullscreen mode
  • An lvalue can be assigned to another lvalue.
int a = 10;
int b = a; // VALID
Enter fullscreen mode Exit fullscreen mode
  • A function that returns a rvalue is also a rvalue
int getValue() {
  return 10;
}

int main() {
  getValue() = 20; // ERROR
}

Enter fullscreen mode Exit fullscreen mode
  • A function that returns a lvalue is also a lvalue
int& getValue() {
  static int a = 10;
  return a;
}

int main() {
  getValue() = 20; // NO ERRORS.
}

Enter fullscreen mode Exit fullscreen mode

lvalue and rvalue references

This is mainly important when dealing with functions.

  • A lvalue can be taken as a parameter using & operator
void setValue(int& a) {
 // Do something
}
Enter fullscreen mode Exit fullscreen mode
  • A rvalue can be taken as a parameter using && operator
void setValue (int&& a) {
 // Do something
}
Enter fullscreen mode Exit fullscreen mode
  • A const lvalue reference can be assigned to an rvalue
int& a = 10; // NOT VALID
const int& b = 10; // VALID 
Enter fullscreen mode Exit fullscreen mode

This is the reason why int C++ a function that accepts a string reference should always be assigned with const.

// accepts only lvalue
void showFullName_1(string& fullName) {
 cout<<fullName<<endl;
} 

// accepts both lvalue and rvalue
void showFullName_2(const string& fullName) {
 cout << fullName <<endl;
}

// accepts only rvalue
void showFullName_3(string&& fullName) {
 cout << fullName <<endl;
}

int main() {
  string firstName = "john";
  string lastName = "doe";
  string fullName = firstName + lastName; //assigning to an lvalue

  showFullName_1(fullName); //works
  showFullName_1(firstName + lastName); // doesn't work because firstName + lastName is a rvalue

  showFullName_2(fullName); // works
  showFullName_2(firstName + lastName); // works

  showFullName_3(fullName); // doesn't work
  showFullName_3(firstName + lastName); // works

}
Enter fullscreen mode Exit fullscreen mode

Hope this gives you a basic understanding of what lvalues and rvalues are. If you found this helpful please share and comment!

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

While many AI coding tools operate as simple command-response systems, Qodo Gen 1.0 represents the next generation: autonomous, multi-step problem-solving agents that work alongside you.

Read full post →

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay