g++ error message when signedness of int type doesn't match

155 views Asked by At

This is easiest if I just start with a sample program. (Note: my question is not about how to fix this program. Please do not reply if your answer is just about how to fix this program and not about my question.)

void f(int &x) { x = 1; }

int main(int, char **)
{
  unsigned int x;

  f(x);

  return 0;
}

Of course the problem here is that f wants to take a signed int as a reference, whereas I'm trying to pass it an unsigned int.

However, the compiler warning from g++ is mystifying:

<source>: In function 'int main(int, char**)':

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

    7 |   f(x);

      |     ^

<source>:1:13: note:   initializing argument 1 of 'void f(int&)'

    1 | void f(int &x) { x = 1; }

      |        ~~~~~^

In case that goes off the side of your screen and you don't want to scroll, the error message is "cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'"

My best guess here is that it tried to implicitly convert an lvalue of type unsigned int to an rvalue of type int and then got stuck. But why would it report results halfway through this attempt? And why does it not report the type unsigned int anywhere here?

clang is markedly more helpful:

<source>:7:3: error: no matching function for call to 'f'

  f(x);

  ^

<source>:1:6: note: candidate function not viable: no known conversion from 'unsigned int' to 'int &' for 1st argument

void f(int &x) { x = 1; }

Question: What is going on here? I assume the compiler has to be trying a conversion to see if it helps and failing, but it makes no sense that the error message would then be issued halfway through this process and wouldn't reference the original type.

2

There are 2 answers

1
Dinesh On

you have to pass the address of the unsigned int to the function.

void f(int *x) { *x = 1; }

int main(int, char **)
{
  unsigned int x;

  f(&x);

  return 0;
}

This program will still give you an error as you are passing unsigned int as the function only accepts int.

1
micron On

You cannot pass an address of another data type to a function.

You must convert the pointer type to unsigned int before sending its address.

void f(int *x) { *x = 1; }

int main(int, char **)
{
    unsigned int x;

    f(reinterpret_cast<int *>(&x));

    return 0;
}

OR

void f(int &x) { x = 1; }

int main(int, char **)
{
    unsigned int x;

    f((int&)x);

    return 0;
}