Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Why this works?

Reply
Thread Tools

Why this works?

 
 
alexstrf@gmail.com
Guest
Posts: n/a
 
      12-20-2012
I have this:

#include <iostream>

int& foo() {}

int main(void)
{
foo() = 1 + 1;

std::cout << foo() << std::endl;

return 0;
}


Compiling with gcc it works,
when executing the output is "2".

What the hell is this and why this works?


Alex
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      12-20-2012
On 12/20/2012 9:00 AM, wrote:
> I have this:
>
> #include <iostream>
>
> int& foo() {}
>
> int main(void)
> {
> foo() = 1 + 1;
>
> std::cout << foo() << std::endl;
>
> return 0;
> }
>
>
> Compiling with gcc it works,
> when executing the output is "2".
>
> What the hell is this and why this works?


You need to ask folks who implemented gcc. The Standard doesn't specify
what should happen when a function that's supposed to return something
does not return it. It's what's known as "undefined behavior" (UB).
Read up on it and try to write code that doesn't have it, and at the
least does not depend on it.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Rui Maciel
Guest
Posts: n/a
 
      12-20-2012
wrote:

> I have this:
>
> #include <iostream>
>
> int& foo() {}
>
> int main(void)
> {
> foo() = 1 + 1;
>
> std::cout << foo() << std::endl;
>
> return 0;
> }
>
>
> Compiling with gcc it works,
> when executing the output is "2".
>
> What the hell is this and why this works?


In C++, flowing off the end of a function is equivalent to a return with no
value, and a return statement without an expression is only permitted in C++
in functions that don't return a value. Therefore, although the standard
states that this is behavior is undefined, it contradicts other behaviors
defined in standard. Therefore, if it isn't treated as a bug, it should be.


Rui Maciel
 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      12-20-2012
Rui Maciel wrote:

> In C++, flowing off the end of a function is equivalent to a return with
> no value, and a return statement without an expression is only permitted
> in C++ in functions that don't return a value. Therefore, although the
> standard states that this is behavior is undefined, it contradicts other
> behaviors defined in standard. Therefore, if it isn't treated as a bug,
> it should be.


I've submitted a bug report, which is available at:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55767


Rui Maciel
 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      12-20-2012
Victor Bazarov wrote:

> You need to ask folks who implemented gcc. The Standard doesn't specify
> what should happen when a function that's supposed to return something
> does not return it. It's what's known as "undefined behavior" (UB).


The standard actually states that a return statement without an expression
can only be used in functions that do not return a value, which is a clear
indication that going against this behavior constitutes a problem.

The only problem that is present in the standard is that a loophole was
explicitly added for this specific case, in which the standard specifies
that when this happens then essentially they let each implementation do what
they wish. Nevertheless, among the list of "permissible undefined
behavior", they also include the possibility of a compiler throwing an
error. So, in spite of the loophole, there is no excuse for doing the right
thing.


Rui Maciel
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      12-20-2012
On 12/20/2012 2:28 PM, Rui Maciel wrote:
> Victor Bazarov wrote:
>
>> You need to ask folks who implemented gcc. The Standard doesn't specify
>> what should happen when a function that's supposed to return something
>> does not return it. It's what's known as "undefined behavior" (UB).

>
> The standard actually states that a return statement without an expression
> can only be used in functions that do not return a value, which is a clear
> indication that going against this behavior constitutes a problem.


The Standard actually states <<Flowing off the end of a function is
equivalent to a return with no value; this results in undefined behavior
in a value-returning function.>> ([stmt.return]/2, last sentence).

What's against what here? Specifying a 'return' without an expression
is prohibited in a value-returning function. But it doesn't say that
absence is "specifying". It says "equivalent", and it most likely means
"equivalent behaviorally" not "equivalent syntactically".

> The only problem that is present in the standard is that a loophole was
> explicitly added for this specific case, in which the standard specifies
> that when this happens then essentially they let each implementation do what
> they wish. Nevertheless, among the list of "permissible undefined
> behavior", they also include the possibility of a compiler throwing an
> error. So, in spite of the loophole, there is no excuse for doing the right
> thing.


Did you mean "no excuse for NOT doing the right thing"?

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      12-21-2012
Victor Bazarov wrote:

> On 12/20/2012 2:28 PM, Rui Maciel wrote:
>> Victor Bazarov wrote:
>>
>>> You need to ask folks who implemented gcc. The Standard doesn't specify
>>> what should happen when a function that's supposed to return something
>>> does not return it. It's what's known as "undefined behavior" (UB).

>>
>> The standard actually states that a return statement without an
>> expression can only be used in functions that do not return a value,
>> which is a clear indication that going against this behavior constitutes
>> a problem.

>
> The Standard actually states <<Flowing off the end of a function is
> equivalent to a return with no value; this results in undefined behavior
> in a value-returning function.>> ([stmt.return]/2, last sentence).


Yes, that was the undefined behavior loophole I've mentioned earlier.


> What's against what here? Specifying a 'return' without an expression
> is prohibited in a value-returning function. But it doesn't say that
> absence is "specifying". It says "equivalent", and it most likely means
> "equivalent behaviorally" not "equivalent syntactically".


The standard states that the behavior is equivalent, without adding any
adjective to narrow out in what sense it should and should not be
equivalent. Hence, the standard only states that flowing off the end of a
function corresponds to the same language construct as a return statement
without an expression, which is not a valid construct according to the
standard, if this happens in a function which does return a value.

The only thing that makes flowing off a function not an error in C++ is the
undefined behavior loophole, whose only effect is to grant implementations
some leeway to deal however they wish with this, which often ends up in
disaster, as we've seen in this case.


>> The only problem that is present in the standard is that a loophole was
>> explicitly added for this specific case, in which the standard specifies
>> that when this happens then essentially they let each implementation do
>> what
>> they wish. Nevertheless, among the list of "permissible undefined
>> behavior", they also include the possibility of a compiler throwing an
>> error. So, in spite of the loophole, there is no excuse for doing the
>> right thing.

>
> Did you mean "no excuse for NOT doing the right thing"?


Yes, oops.


Rui Maciel
 
Reply With Quote
 
Richard Damon
Guest
Posts: n/a
 
      12-21-2012
On 12/20/12 1:53 PM, Rui Maciel wrote:
> wrote:
>
>> I have this:
>>
>> #include <iostream>
>>
>> int& foo() {}
>>
>> int main(void)
>> {
>> foo() = 1 + 1;
>>
>> std::cout << foo() << std::endl;
>>
>> return 0;
>> }
>>
>>
>> Compiling with gcc it works,
>> when executing the output is "2".
>>
>> What the hell is this and why this works?

>
> In C++, flowing off the end of a function is equivalent to a return with no
> value, and a return statement without an expression is only permitted in C++
> in functions that don't return a value. Therefore, although the standard
> states that this is behavior is undefined, it contradicts other behaviors
> defined in standard. Therefore, if it isn't treated as a bug, it should be.
>
>
> Rui Maciel
>


The issue is that in general, the compiler can not be always know if the
function can flow off the end of the function, as it requires solving
the halting problem, and the compiler may be missing key information to
even try it.

For example, should this be required to generate a diagnostic?

int foo() {
bar();
}

What if bar always calls exit()?, or throws?

Because of this problem, the standard should require a diagnostic for a
"possible" path from flowing off the end, and the committee probably
felt it wasn't worth trying to define a set of minimal cases that a
certain to do so (because it actually is fairly hard to do at the level
of rigor required by the standard).

Now it does turn out that many cases, like the one presented originally,
can often be detected by the compiler, and thus a "good" compiler will
issue a warning where it can detect that this is the likely case.
 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      12-21-2012
Richard Damon <> writes:
> int foo() {
> bar();
> }
> What if bar always calls exit()?, or throws?


Then foo should have type void rather than int.
 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      12-21-2012
Robert Wessel <> writes:
> int foo() {
> if (somecondition)
> return 7;
> else
> bar(); // never returns
> }


I'd want the compiler to signal a type error here, unless the type of
bar() is int. I don't know what the standard says about the situation
though.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Cisco 2611 and Cisco 1721 : Why , why , why ????? sam@nospam.org Cisco 10 05-01-2005 08:49 AM
Why, why, why??? =?Utf-8?B?VGltOjouLg==?= ASP .Net 6 01-27-2005 03:35 PM
Why Why Why You HAVE NO IDEA MCSE 31 04-24-2004 06:40 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57