Initialisation of reference vs. initialisation of reference member

Discussion in 'C++' started by Tim Clacy, May 30, 2006.

  1. Tim Clacy

    Tim Clacy Guest

    1) Is this initialising the reference 'u' to the address of the literal '2'
    or to the address 0x00000002?

    unsigned const& u = 2;


    2) What is the different between the initialisation of 'u' and 'S::u' below?

    unsigned const& u = 2;

    struct S
    {
    unsigned const& u;

    S() : u (2) { }

    } s;

    int main(int argc, char* argv[])
    {
    return 0;
    }


    VisualStudio 2005 generates "error C2354: 'S::u' : initialization of
    reference member requires a temporary variable" but does not complain about
    the initialisation of 'u'. A couple of other compilers that I have say
    nothing about either (GCC 3.3.4, ADS 1.2).


    Any illumination will be greatly appreciated.


    Tim
    Tim Clacy, May 30, 2006
    #1
    1. Advertising

  2. Tim Clacy

    Jim Langston Guest

    "Tim Clacy" <> wrote in message
    news:447bf6f8$0$38638$...
    > 1) Is this initialising the reference 'u' to the address of the literal
    > '2' or to the address 0x00000002?
    >
    > unsigned const& u = 2;


    Easy enough to find out:
    std::cout << u;
    outputs
    2
    so it would initializing the reference to be the address where the constant
    unsigned int is stored.
    Jim Langston, May 30, 2006
    #2
    1. Advertising

  3. Tim Clacy

    Tim Clacy Guest

    Jim Langston wrote:
    > "Tim Clacy" <> wrote in message
    > news:447bf6f8$0$38638$...
    >> 1) Is this initialising the reference 'u' to the address of the
    >> literal '2' or to the address 0x00000002?
    >>
    >> unsigned const& u = 2;

    >
    > Easy enough to find out:
    > std::cout << u;
    > outputs
    > 2
    > so it would initializing the reference to be the address where the
    > constant unsigned int is stored.


    Hi Jim,

    Thanks for replying. I think all you code proves is that the value of u is
    2; it doesn't really prove that this is because the reference has been
    initialised to the address of a literal 2 or because a word access to
    address 2 returns 2.
    Tim Clacy, May 30, 2006
    #3
  4. Tim Clacy

    shailesh Guest

    I tried running this:

    unsigned const int& n = 3;
    cout << n << endl;
    cout << &n << endl;

    Output is:
    3
    0012FEC8

    During debugging I can see that memory location 0012FEC8 has the value
    3 stored.

    This is on VC++ 2003 compiler.

    So this answers question 1.

    2:

    About the error you saw, MSDN says this:
    'reference' : initialization of reference member requires a temporary
    variable

    A constructor initializes a reference to a member instead of
    initializing the member.

    It is invalid to initialize a reference member of a class in the
    class's constructor with a temporary variable. An attempt to do so
    generates the C2354 error, as illustrated by this sample code:

    // C2354.cpp
    int temp() { return 1; }
    class Test
    {
    public:
    int member;
    int& ref_member;
    Test();
    };

    Test::Test() : ref_member( temp() )
    { // C2354
    }
    When this error is encountered, the solution is to change the code so
    that the reference member is not initialized to a temporary variable.
    The reference must be initialized to an object that will exist for the
    lifetime of the reference member.
    ------------------------------------------------------------------------------------

    So it seems that the 2 in the constructor call is being treated as a
    temporary variable. and not as something in the global memory.
    shailesh, May 30, 2006
    #4
  5. Tim Clacy

    Tim Clacy Guest

    shailesh wrote:
    > I tried running this:
    >
    > unsigned const int& n = 3;
    > cout << n << endl;
    > cout << &n << endl;
    >
    > Output is:
    > 3
    > 0012FEC8
    >
    > During debugging I can see that memory location 0012FEC8 has the value
    > 3 stored.
    >
    > This is on VC++ 2003 compiler.
    >
    > So this answers question 1.
    >
    > 2:
    >
    > About the error you saw, MSDN says this:
    > 'reference' : initialization of reference member requires a temporary
    > variable
    >
    > A constructor initializes a reference to a member instead of
    > initializing the member.
    >
    > It is invalid to initialize a reference member of a class in the
    > class's constructor with a temporary variable. An attempt to do so
    > generates the C2354 error, as illustrated by this sample code:
    >
    > // C2354.cpp
    > int temp() { return 1; }
    > class Test
    > {
    > public:
    > int member;
    > int& ref_member;
    > Test();
    > };
    >
    > Test::Test() : ref_member( temp() )
    > { // C2354
    > }
    > When this error is encountered, the solution is to change the code so
    > that the reference member is not initialized to a temporary variable.
    > The reference must be initialized to an object that will exist for the
    > lifetime of the reference member.
    > ------------------------------------------------------------------------------------
    >
    > So it seems that the 2 in the constructor call is being treated as a
    > temporary variable. and not as something in the global memory.


    Hi shailesh,

    That's very interesting but the Microsoft compiler error that I saw was '
    initialization of
    reference member requires a temporary variable'. This is quite the opposite
    of what the MSDN article says (reference member must NOT be initialised to a
    temporary).

    I'm a little more confused now :-(
    Tim Clacy, May 30, 2006
    #5
  6. Tim Clacy

    John Carson Guest

    "shailesh" <> wrote in message
    news:
    >
    > 2:
    >
    > About the error you saw, MSDN says this:
    > 'reference' : initialization of reference member requires a temporary
    > variable
    >
    > A constructor initializes a reference to a member instead of
    > initializing the member.
    >
    > It is invalid to initialize a reference member of a class in the
    > class's constructor with a temporary variable. An attempt to do so
    > generates the C2354 error, as illustrated by this sample code:
    >
    > // C2354.cpp
    > int temp() { return 1; }
    > class Test
    > {
    > public:
    > int member;
    > int& ref_member;
    > Test();
    > };
    >
    > Test::Test() : ref_member( temp() )
    > { // C2354
    > }
    > When this error is encountered, the solution is to change the code so
    > that the reference member is not initialized to a temporary variable.
    > The reference must be initialized to an object that will exist for the
    > lifetime of the reference member.
    > ------------------------------------------------------------------------------------
    >
    > So it seems that the 2 in the constructor call is being treated as a
    > temporary variable. and not as something in the global memory.


    On the other hand, Comeau online compiles the code without complaint.

    --
    John Carson
    John Carson, May 30, 2006
    #6
  7. Tim Clacy

    Tim Clacy Guest

    John Carson wrote:
    > "shailesh" <> wrote in message
    > news:
    >>
    >> 2:
    >>
    >> About the error you saw, MSDN says this:
    >> 'reference' : initialization of reference member requires a temporary
    >> variable
    >>
    >> A constructor initializes a reference to a member instead of
    >> initializing the member.
    >>
    >> It is invalid to initialize a reference member of a class in the
    >> class's constructor with a temporary variable. An attempt to do so
    >> generates the C2354 error, as illustrated by this sample code:
    >>
    >> // C2354.cpp
    >> int temp() { return 1; }
    >> class Test
    >> {
    >> public:
    >> int member;
    >> int& ref_member;
    >> Test();
    >> };
    >>
    >> Test::Test() : ref_member( temp() )
    >> { // C2354
    >> }
    >> When this error is encountered, the solution is to change the code so
    >> that the reference member is not initialized to a temporary variable.
    >> The reference must be initialized to an object that will exist for
    >> the lifetime of the reference member.
    >> ------------------------------------------------------------------------------------
    >>
    >> So it seems that the 2 in the constructor call is being treated as a
    >> temporary variable. and not as something in the global memory.

    >
    > On the other hand, Comeau online compiles the code without complaint.


    Hi John, so does GCC 3.3.4 for ARM and it behaves as expected at run-time
    too.
    Tim Clacy, May 30, 2006
    #7
  8. Tim Clacy

    Tomás Guest

    Tim Clacy posted:

    > 1) Is this initialising the reference 'u' to the address of the
    > literal '2' or to the address 0x00000002?
    >
    > unsigned const& u = 2;



    C++ handles this under the hood as:


    unsigned const literal_2 = 2;

    unsigned const &u = literal_2;



    > 2) What is the different between the initialisation of 'u' and 'S::u'
    > below?
    >
    > unsigned const& u = 2;
    >
    > struct S
    > {
    > unsigned const& u;
    >
    > S() : u (2) { }
    >
    > } s;



    No difference. However, the global variable is far more likely to simply
    be optimized to:

    unsigned const u = 2;



    > VisualStudio 2005 generates "error C2354: 'S::u' : initialization of
    > reference member requires a temporary variable" but does not complain
    > about the initialisation of 'u'.



    The code compiles without error and without warning with the G++
    compiler.


    When in doubt, presume Microsoft's incompetence.


    -Tomás
    Tomás, May 30, 2006
    #8
  9. Tim Clacy

    Tim Clacy Guest

    Tomás wrote:
    > Tim Clacy posted:
    >
    >> 1) Is this initialising the reference 'u' to the address of the
    >> literal '2' or to the address 0x00000002?
    >>
    >> unsigned const& u = 2;

    >
    >
    > C++ handles this under the hood as:
    >
    >
    > unsigned const literal_2 = 2;
    >
    > unsigned const &u = literal_2;
    >
    >
    >
    >> 2) What is the different between the initialisation of 'u' and 'S::u'
    >> below?
    >>
    >> unsigned const& u = 2;
    >>
    >> struct S
    >> {
    >> unsigned const& u;
    >>
    >> S() : u (2) { }
    >>
    >> } s;

    >
    >
    > No difference. However, the global variable is far more likely to
    > simply be optimized to:
    >
    > unsigned const u = 2;
    >
    >
    >
    >> VisualStudio 2005 generates "error C2354: 'S::u' : initialization of
    >> reference member requires a temporary variable" but does not complain
    >> about the initialisation of 'u'.

    >
    >
    > The code compiles without error and without warning with the G++
    > compiler.
    >
    >
    > When in doubt, presume Microsoft's incompetence.
    >
    >
    > -Tomás


    Thanks very much Tomás
    Tim Clacy, May 30, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Samuele Armondi
    Replies:
    4
    Views:
    1,017
    Victor Bazarov
    Jun 25, 2003
  2. Jason Heyes
    Replies:
    6
    Views:
    367
    Norbert Riedlin
    Dec 4, 2003
  3. Tim
    Replies:
    2
    Views:
    1,494
  4. santosh

    member const initialisation

    santosh, May 23, 2005, in forum: C++
    Replies:
    3
    Views:
    419
    Lionel B
    May 23, 2005
  5. Taras_96
    Replies:
    10
    Views:
    605
    Pavel
    Oct 31, 2009
Loading...

Share This Page