Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
879 views
in Technique[技术] by (71.8m points)

gcc - Passing non-const references to rvalues in C++

In the following line of code:

bootrec_reset(File(path, size, off), blksize);

Calling a function with prototype:

static void bootrec_reset(File &file, ssize_t blksize);

I receive this error:

libcpfs/mkfs.cc:99:53: error: invalid initialization of non-const reference of type 'File&' from an rvalue of type 'File'

libcpfs/mkfs.cc:30:13: error: in passing argument 1 of 'void bootrec_reset(File&, ssize_t)'

I'm aware that you can not pass non-const references (const &) to rvalues according to the standard. MSVC however allows you to do this (see this question). This question attempts to explain why but the answer makes no sense as he is using references to literals, which are a corner case and should obviously be disallowed.

In the given example it's clear to see that following order of events will occur (as it does in MSVC):

  1. File's constructor will be called.
  2. A reference to the File, and blksize, are pushed on the stack.
  3. bootrec_reset makes use of file.
  4. After returning from bootrec_reset, the temporary File is destroyed.

It's necessary to point out that the File reference needs to be non-const, as it's a temporary handle to a file, on which non-const methods are invoked. Furthermore I don't want to pass the File's constructor arguments to bootrec_reset to be constructed there, nor do I see any reason to manually construct and destroy a File object in the caller.

So my questions are:

  1. What justifies the C++ standard disallowing non-const references in this manner?
  2. How can I force GCC to permit this code?
  3. Does the upcoming C++0x standard change this in anyway, or is there something the new standard gives me that is more appropriate here, for example all that jibberish about rvalue references?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Yes, the fact that plain functions cannot bind non-const references to temporaries -- but methods can -- has always bugged me. TTBOMK the rationale goes something like this (sourced from this comp.lang.c++.moderated thread):

Suppose you have:

 void inc( long &x ) { ++x; }

 void test() {
     int y = 0;
     inc( y );
     std::cout << y;
 } 

If you allowed the long &x parameter of inc() to bind to a temporary long copy made from y, this code obviously wouldn't do what you expect -- the compiler would just silently produce code that leaves y unchanged. Apparently this was a common source of bugs in the early C++ days.

Had I designed C++, my preference would have been to allow non-const references to bind to temporaries, but to forbid automatic conversions from lvalues to temporaries when binding to references. But who knows, that might well have opened up a different can of worms...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...