voltrevo
voltrevo

Reputation: 10459

How does C++ handle a const double& that refers to an int?

I was working on some template code this morning where I used a BOOST_STATIC_ASSERT to ensure I wasn't creating a reference to the wrong type, as I thought it might be a clearer error message. However when I tried removing the static assert to take a look at the alternative compiler error I was shocked to discover that gcc doesn't even complain when you try to make a const double& referring to an int:

#include <iostream>

int main()
{
    int x = 5;
    const double& y = x;
    std::cout << y << std::endl;

    return 0;
}

Compiles, and doesn't even warn:

$ g++ ~/stuff/badRef.cpp -Wall -Wextra -pedantic
$ a.out
5

What's going on here? Is this undefined behaviour? If so why doesn't gcc complain? On my machine int is 4 bytes and a double is 8. That means that when printing a double& it should interpret 8 bytes at that address as a double and print it, yet there is actually a 4 byte int at that location.

Very confused. Help!

Upvotes: 18

Views: 4486

Answers (4)

ildjarn
ildjarn

Reputation: 62975

const double& y = x; creates a temporary double with the value static_cast<double>(x), then binds that temporary to y. The lifetime of the temporary is extended to match the lifetime of y.

This is completely legal C++ (03 and 11), hence the lack of warning/error.

Upvotes: 23

Jon Purdy
Jon Purdy

Reputation: 54971

const T& can bind to a temporary, so x is being converted to double and the copy is bound to y. If you check, you’ll see that &x != &y. The reason for this behaviour is to allow passing literals to functions that take their parameters by const reference.

Upvotes: 2

justin
justin

Reputation: 104698

it's well defined and legal. y refers to a temporary. consider also when you pass parameters:

void foo(const int& p);
foo(3.14);

Note also that this is not valid C++ if the reference is not const. VS 6 got that wrong and allowed binding a mutable reference to a temporary. This applies only to const references.

Upvotes: 11

Johan Lundberg
Johan Lundberg

Reputation: 27028

This is a good example for those who think that pointers and references are the same.

double const*const y2 = &x;

gives
bad.cpp:7:30: error: cannot convert ‘int*’ to ‘const double* const’ in initialization

The reason it works for references is explained in the other posts.

Upvotes: 1

Related Questions