12

Example:

typedef enum Color
{
    RED,
    GREEN,
    BLUE
} Color;

void func(unsigned int& num)
{
    num++;
}

int main()
{
    Color clr = RED;
    func(clr);
    return 0;
}

I get the following error when I compile this:

<source>: In function 'int main()':

<source>:16:9: error: cannot bind non-const lvalue reference of type 'unsigned int&' to an rvalue of type 'unsigned int'

     func(clr);

         ^~~

I think the variable (clr) I pass to func(unsigned int&) is an lvalue. I can get the address of clr and can assign another value to it. Why does it turn into an rvalue when I try to pass it to func(unsigned int&)?

Boann
  • 48,794
  • 16
  • 117
  • 146
Koen
  • 311
  • 2
  • 11
  • 5
    Ask yourself: Is an `enum` a `unsigned int`? – NathanOliver Dec 31 '19 at 07:10
  • @NathanOliver-ReinstateMonica In my original opinion, I think `typedef enum` is not a native type, and C++ would treat it as an `unsigned int` type indeed. – Koen Dec 31 '19 at 07:24
  • 1
    GCC's error message is suboptimal in this case. Clang will give a less confusing message by printing the original type of `clr`. – cpplearner Dec 31 '19 at 08:54
  • @cpplearner yep, that's why I thought `enum type` is treat as `unsigned int` in C++. – Koen Dec 31 '19 at 09:02
  • `enum X` is its own type, distinct from `int` – M.M Dec 31 '19 at 13:51
  • The compiler can choose to make the type for instance `unsigned char`. Then there is indeed a mismatch in type. Since the compiler must be free to choose the type, an error is generated. – Klaas van Aarsen Dec 31 '19 at 22:16
  • What happens if you type `typedef enum Color : unsigned int`? – S.S. Anne Dec 31 '19 at 22:38
  • @JL2210 Sorry, I dont get it. What's this type for? – Koen Dec 31 '19 at 23:17
  • Typed enums. It allows you to specify the type of an enum's members – S.S. Anne Dec 31 '19 at 23:24
  • @JL2210 O I see. I try it and get the same result. Seems it still would implicitly convert to rvalue if I keep passing a not `unsigned int` type lvalue to `unsigned int&`. – Koen Dec 31 '19 at 23:33

2 Answers2

22

clr itself is an lvalue of type Color. But the function does not accept a Color. It accepts a (reference to) unsigned int. So, the argument is converted (implicitly). And the result of the conversion is a prvalue of type unsigned int.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • 1
    Yep, I try `func(Color&)` before I ask the question, and it compile pass. I just thought C++ would treat `enum` type as `unsigned int` type in compiling. Thanks for your answer. – Koen Dec 31 '19 at 07:31
  • One thing that adds to the confusion is that C is almost a perfect subset of C++. At least, anything you can do in C, you can do in C++ with almost identical code, especially on gcc/clang. You will also need compiler dependent constructs as the C++ replacement for 'restrict' in C that is provided by gcc. Enums are different in C and C++, for example, if someColor is enum, 'someColor = 1' is legal C, but not C++. – Erik Alapää Jan 01 '20 at 10:52
0

enum type init and assignment must be enum inside,so enum type can't is lvalue。 void func(unsigned int& num) this function need quote type

superman
  • 48
  • 3
  • If I change `func(unsigned int&)` to `func(Color&)`, compiler accept it. So I think enum type variable is a lvalue. – Koen Dec 31 '19 at 07:27
  • no, because enum type can't assignment int enum define outside – superman Dec 31 '19 at 07:30
  • You mean it still a rvalue? But I bind a not-const lvalue reference to it in `func(Color&)`, and it pass. – Koen Dec 31 '19 at 07:38
  • yes, it still a rvalue,func(Color& key) this function param key only assignment RED,GREEN,BLUE , Otherwise it will error。 – superman Dec 31 '19 at 07:47
  • you can see [this cpp instructions](https://en.cppreference.com/w/cpp/language/enum) – superman Dec 31 '19 at 07:50
  • thanks for link shared. I know a enum type variable can only accept the value within its enum defined scope. But is it the reason that make enum type variable be a `rvalue`? – Koen Dec 31 '19 at 07:58
  • @Koen the problem is not with the enum. You'd get a similar error if you called e.g. `func(5u);` – Ruslan Dec 31 '19 at 16:38
  • Thanks @Ruslan. I think the comments under this answer is outside the original question. I just could't agree with the opinion of `enum type variable is rvalue` in the answer. – Koen Dec 31 '19 at 23:36