diff mbox series

[doc] correct/expand -Wreturn-type

Message ID c2c50769-9c77-e1eb-e8f5-2ed33cc1b619@gmail.com
State New
Headers show
Series [doc] correct/expand -Wreturn-type | expand

Commit Message

Martin Sebor Feb. 6, 2019, 4:51 p.m. UTC
A recent flurry of bug reports about wrong code in C++ due to flowing
(AKA falling) off the end of a function prompted me to look at what
the manual has to say about the undefined behavior that the warning
is meant to point out.  It turns out that the manual not only doesn't
mention it, but it also incorrectly states that in C++, -Wreturn-type
cannot be suppressed by -Wno-return-type.

The attached patch documents the undefined behavior and removes
the statement about -Wno-return-type having no effect in C++.

Martin

PS The C++ standard uses the term "flow of the end" so I used that
in the new text even though the C paragraph refers to it as "falling
off the end."

Comments

Jakub Jelinek Feb. 6, 2019, 4:56 p.m. UTC | #1
On Wed, Feb 06, 2019 at 09:51:59AM -0700, Martin Sebor wrote:
> -For C++, a function without return type always produces a diagnostic
> -message, even when @option{-Wno-return-type} is specified.  The only
> -exceptions are @code{main} and functions defined in system headers.
> +For C++, calling a non-@code{void} function other than @code{main} that flows
> +off the end is undefined even if the value of the function is not used.

That is not true, the undefined behavior is not when calling such a function,
but only when it flows off the end.  So, it is perfectly fine if you have:
int
foo (int x)
{
  if (x > 10)
    return 20;
}
and you only ever call foo with x > 10, or if you have:
int
bar ()
{
  baz ();
}
and baz always throws, or never returns etc.  So, if we try to clarify, we
should clarify it correctly.

	Jakub
Martin Sebor Feb. 6, 2019, 5:15 p.m. UTC | #2
On 2/6/19 9:56 AM, Jakub Jelinek wrote:
> On Wed, Feb 06, 2019 at 09:51:59AM -0700, Martin Sebor wrote:
>> -For C++, a function without return type always produces a diagnostic
>> -message, even when @option{-Wno-return-type} is specified.  The only
>> -exceptions are @code{main} and functions defined in system headers.
>> +For C++, calling a non-@code{void} function other than @code{main} that flows
>> +off the end is undefined even if the value of the function is not used.
> 
> That is not true, the undefined behavior is not when calling such a function,
> but only when it flows off the end.  So, it is perfectly fine if you have:
> int
> foo (int x)
> {
>    if (x > 10)
>      return 20;
> }
> and you only ever call foo with x > 10, or if you have:
> int
> bar ()
> {
>    baz ();
> }
> and baz always throws, or never returns etc.  So, if we try to clarify, we
> should clarify it correctly.

Sigh.  Was that jab really necessary?

The C++ standard says:

   ...flowing off the end of a function other than main (6.6.1)
   results in undefined behavior.

It doesn't mention anything about calling the function so it seems
to me the text I added is no less correct or clear than that.  I see
no point in going into unlikely corner cases that the standard itself
make provisions for.

Martin
Jakub Jelinek Feb. 6, 2019, 5:20 p.m. UTC | #3
On Wed, Feb 06, 2019 at 10:15:27AM -0700, Martin Sebor wrote:
> > > -For C++, a function without return type always produces a diagnostic
> > > -message, even when @option{-Wno-return-type} is specified.  The only
> > > -exceptions are @code{main} and functions defined in system headers.
> > > +For C++, calling a non-@code{void} function other than @code{main} that flows
> > > +off the end is undefined even if the value of the function is not used.
> > 
> > That is not true, the undefined behavior is not when calling such a function,
> > but only when it flows off the end.  So, it is perfectly fine if you have:
> > int
> > foo (int x)
> > {
> >    if (x > 10)
> >      return 20;
> > }
> > and you only ever call foo with x > 10, or if you have:
> > int
> > bar ()
> > {
> >    baz ();
> > }
> > and baz always throws, or never returns etc.  So, if we try to clarify, we
> > should clarify it correctly.
> 
> Sigh.  Was that jab really necessary?
> 
> The C++ standard says:
> 
>   ...flowing off the end of a function other than main (6.6.1)
>   results in undefined behavior.
> 
> It doesn't mention anything about calling the function so it seems
> to me the text I added is no less correct or clear than that.  I see
> no point in going into unlikely corner cases that the standard itself
> make provisions for.

Your new text talks about calling the function though, which might be read as that
the UB is already when you call such a function.  Why don't you use the
standard wording instead, i.e.
"For C++, flowing off the end of a function other than @code{main} is
undefined even if the return value from the function is not used in the
caller."
or similar?

	Jakub
Jakub Jelinek Feb. 6, 2019, 5:35 p.m. UTC | #4
On Wed, Feb 06, 2019 at 06:20:35PM +0100, Jakub Jelinek wrote:
> "For C++, flowing off the end of a function other than @code{main} is

Oops, either replace function above with value-returning function, or
non-@code{void} function.

> undefined even if the return value from the function is not used in the
> caller."
> or similar?

	Jakub
Martin Sebor Feb. 6, 2019, 6:15 p.m. UTC | #5
On 2/6/19 10:20 AM, Jakub Jelinek wrote:
> On Wed, Feb 06, 2019 at 10:15:27AM -0700, Martin Sebor wrote:
>>>> -For C++, a function without return type always produces a diagnostic
>>>> -message, even when @option{-Wno-return-type} is specified.  The only
>>>> -exceptions are @code{main} and functions defined in system headers.
>>>> +For C++, calling a non-@code{void} function other than @code{main} that flows
>>>> +off the end is undefined even if the value of the function is not used.
>>>
>>> That is not true, the undefined behavior is not when calling such a function,
>>> but only when it flows off the end.  So, it is perfectly fine if you have:
>>> int
>>> foo (int x)
>>> {
>>>     if (x > 10)
>>>       return 20;
>>> }
>>> and you only ever call foo with x > 10, or if you have:
>>> int
>>> bar ()
>>> {
>>>     baz ();
>>> }
>>> and baz always throws, or never returns etc.  So, if we try to clarify, we
>>> should clarify it correctly.
>>
>> Sigh.  Was that jab really necessary?
>>
>> The C++ standard says:
>>
>>    ...flowing off the end of a function other than main (6.6.1)
>>    results in undefined behavior.
>>
>> It doesn't mention anything about calling the function so it seems
>> to me the text I added is no less correct or clear than that.  I see
>> no point in going into unlikely corner cases that the standard itself
>> make provisions for.
> 
> Your new text talks about calling the function though, which might be read as that
> the UB is already when you call such a function.

The purpose of referring to calling the function is to clearly
distinguish the C++ undefined behavior from that in C.  I see
absolutely no value in trying to carefully explain that it is
possible to call functions that forget to return a value without
running into undefined behavior.

> Why don't you use the
> standard wording instead, i.e.
> "For C++, flowing off the end of a function other than @code{main} is
> undefined even if the return value from the function is not used in the
> caller."
> or similar?

You just reversed the two subsentences:

   calling a non-@code{void} function other than @code{main}
   that flows off the end is undefined even if the value of the function
   is not used.

vs

   flowing off the end of a function other than @code{main} is
   undefined even if the return value from the function is not used
   in the caller.

But whatever.  Attached is a change with the subsentences reversed.

Martin
gcc/ChangeLog:

	* doc/invoke.texi (-Wreturn-type): Correct and expand.

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 268583)
+++ gcc/doc/invoke.texi	(working copy)
@@ -5261,13 +5261,16 @@ without a value).
 For C only, warn about a @code{return} statement with an expression in a
 function whose return type is @code{void}, unless the expression type is
 also @code{void}.  As a GNU extension, the latter case is accepted
-without a warning unless @option{-Wpedantic} is used.
+without a warning unless @option{-Wpedantic} is used.  Attempting
+to use the return value of a non-@code{void} function other than @code{main}
+that flows off the end by reaching the closing curly brace that terminates
+the function is undefined.
 
-For C++, a function without return type always produces a diagnostic
-message, even when @option{-Wno-return-type} is specified.  The only
-exceptions are @code{main} and functions defined in system headers.
+Unlike in C, in C++, flowing off the end of a non-@code{void} function other
+than @code{main} results in undefined behavior even when the value of
+the function is not used.
 
-This warning is enabled by default for C++ and is enabled by @option{-Wall}.
+This warning is enabled by default in C++ and by @option{-Wall} otherwise.
 
 @item -Wshift-count-negative
 @opindex Wshift-count-negative
Sandra Loosemore Feb. 16, 2019, 2:16 a.m. UTC | #6
On 2/6/19 11:15 AM, Martin Sebor wrote:
> [snip]
> But whatever.  Attached is a change with the subsentences reversed.

This version of the patch is OK.

-Sandra
diff mbox series

Patch

gcc/ChangeLog:

	* doc/invoke.texi (-Wreturn-type): Correct and expand.

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 268583)
+++ gcc/doc/invoke.texi	(working copy)
@@ -5261,13 +5261,15 @@  without a value).
 For C only, warn about a @code{return} statement with an expression in a
 function whose return type is @code{void}, unless the expression type is
 also @code{void}.  As a GNU extension, the latter case is accepted
-without a warning unless @option{-Wpedantic} is used.
+without a warning unless @option{-Wpedantic} is used.  Attempting
+to use the return value of a non-@code{void} function other than @code{main}
+that flows off the end by reaching the closing curly brace that terminates
+the function is undefined.
 
-For C++, a function without return type always produces a diagnostic
-message, even when @option{-Wno-return-type} is specified.  The only
-exceptions are @code{main} and functions defined in system headers.
+For C++, calling a non-@code{void} function other than @code{main} that flows
+off the end is undefined even if the value of the function is not used.
 
-This warning is enabled by default for C++ and is enabled by @option{-Wall}.
+This warning is enabled by default in C++ and by @option{-Wall} otherwise.
 
 @item -Wshift-count-negative
 @opindex Wshift-count-negative