Topic: proposal: deprecate failure to return (without annotation)


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 29 Sep 2014 15:15:15 -0400
Raw View
Right now, in C++ it is legal to write something like:

  int foo()
  {
    bar(); // assume for now that bar() is not [[noreturn]]
  }

This is almost certainly a bug; foo() was supposed to return something,
but didn't, which will lead to UB when foo() is called. Unfortunately,
while there exists a warning for this in some compilers, it is not
enabled by default.

I have a difficult time thinking of a case where code like this is
intentional.

I'd like to propose that the language be changed such that falling off
the end of a non-void function (i.e. that the compiler can detect that
this legitimately occurs) is ill-formed, unless (a) an annotation
expressing that intent is present, or (b) the compiler detects that the
return value is initialized by some other means (e.g. inline assembly).
The intent is that such functions would raise a compile *error*.

This does not change any ABI, so already compiled code would continue to
work. I would further encourage recommending that compilers provide a
mode switch to disable this behavior in case old, broken code needs to
be compiled.

What do folks think?



I'd prefer to leave open the syntax for declaring when such a function
falls off the end intentionally. An attribute seems most natural
(although I haven't been able to come up with a reasonable name for
one), but might trip over the 'attributes do not change semantics' rule.

Another option would be:

  int foo() -> (void)
  { ... }

Note the use of ()'s in an effort to allow this to work with trailing
return type as well, e.g.:

  auto foo() -> (void) int
  { ... }

(Standardizing a method to tell the compiler that some code is
unreachable in case it is unable to so deduce might be relevant.)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 29 Sep 2014 12:51:47 -0700
Raw View
On Monday 29 September 2014 15:15:15 Matthew Woehlke wrote:
> I'd like to propose that the language be changed such that falling off
> the end of a non-void function (i.e. that the compiler can detect that
> this legitimately occurs) is ill-formed, unless (a) an annotation
> expressing that intent is present, or (b) the compiler detects that the
> return value is initialized by some other means (e.g. inline assembly).
> The intent is that such functions would raise a compile *error*.

Would this be ill-formed:

int foo(int x)
{
 if (x == 1)
  return doOne();
 else if (x == 2)
  return doTwo();
}

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 29 Sep 2014 12:52:04 -0700
Raw View
--047d7b3a7e30dce9770504399915
Content-Type: text/plain; charset=UTF-8

On Mon, Sep 29, 2014 at 12:15 PM, Matthew Woehlke <
mw_triad@users.sourceforge.net> wrote:

> Right now, in C++ it is legal to write something like:
>
>   int foo()
>   {
>     bar(); // assume for now that bar() is not [[noreturn]]
>   }
>
> This is almost certainly a bug; foo() was supposed to return something,
> but didn't, which will lead to UB when foo() is called. Unfortunately,
> while there exists a warning for this in some compilers, it is not
> enabled by default.
>
> I have a difficult time thinking of a case where code like this is
> intentional.
>
> I'd like to propose that the language be changed such that falling off
> the end of a non-void function (i.e. that the compiler can detect that
> this legitimately occurs) is ill-formed, unless (a) an annotation
> expressing that intent is present, or (b) the compiler detects that the
> return value is initialized by some other means (e.g. inline assembly).
> The intent is that such functions would raise a compile *error*.
>
> This does not change any ABI, so already compiled code would continue to
> work. I would further encourage recommending that compilers provide a
> mode switch to disable this behavior in case old, broken code needs to
> be compiled.
>
> What do folks think?
>

Consider:

enum E { a, b, c };
int f(E e) {
  switch (e) {
  case a: return 1;
  case b: return 2;
  case c: return 3;
  }
}

Should this be rejected? f might be legitimately called with e == (E)3.
Some compilers look at this and say "well, it looks like you intend for e
to only take values that are named enumerators of E here, so I will not
warn on this".

I strongly think we should leave this in the hands of compiler implementors
and not try to mandate some diagnostics here.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--047d7b3a7e30dce9770504399915
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Sep 29, 2014 at 12:15 PM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mw_triad@users.sourceforge.net" target=3D"_blank">mw_triad@users=
..sourceforge.net</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ri=
ght now, in C++ it is legal to write something like:<br>
<br>
=C2=A0 int foo()<br>
=C2=A0 {<br>
=C2=A0 =C2=A0 bar(); // assume for now that bar() is not [[noreturn]]<br>
=C2=A0 }<br>
<br>
This is almost certainly a bug; foo() was supposed to return something,<br>
but didn&#39;t, which will lead to UB when foo() is called. Unfortunately,<=
br>
while there exists a warning for this in some compilers, it is not<br>
enabled by default.<br>
<br>
I have a difficult time thinking of a case where code like this is<br>
intentional.<br>
<br>
I&#39;d like to propose that the language be changed such that falling off<=
br>
the end of a non-void function (i.e. that the compiler can detect that<br>
this legitimately occurs) is ill-formed, unless (a) an annotation<br>
expressing that intent is present, or (b) the compiler detects that the<br>
return value is initialized by some other means (e.g. inline assembly).<br>
The intent is that such functions would raise a compile *error*.<br>
<br>
This does not change any ABI, so already compiled code would continue to<br=
>
work. I would further encourage recommending that compilers provide a<br>
mode switch to disable this behavior in case old, broken code needs to<br>
be compiled.<br>
<br>
What do folks think?<br></blockquote><div><br></div><div>Consider:</div><di=
v><br></div><div>enum E { a, b, c };</div><div>int f(E e) {</div><div>=C2=
=A0 switch (e) {</div><div>=C2=A0 case a: return 1;</div><div>=C2=A0 case b=
: return 2;</div><div>=C2=A0 case c: return 3;</div><div>=C2=A0 }</div><div=
>}</div><div>=C2=A0</div><div>Should this be rejected? f might be legitimat=
ely called with e =3D=3D (E)3. Some compilers look at this and say &quot;we=
ll, it looks like you intend for e to only take values that are named enume=
rators of E here, so I will not warn on this&quot;.</div><div><br></div><di=
v>I strongly think we should leave this in the hands of compiler implemento=
rs and not try to mandate some diagnostics here.</div></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b3a7e30dce9770504399915--

.


Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Mon, 29 Sep 2014 22:02:36 +0200
Raw View
2014-09-29 21:52 GMT+02:00 Richard Smith <richard@metafoo.co.uk>:
> On Mon, Sep 29, 2014 at 12:15 PM, Matthew Woehlke
> <mw_triad@users.sourceforge.net> wrote:
>>
>> Right now, in C++ it is legal to write something like:
>>
>>   int foo()
>>   {
>>     bar(); // assume for now that bar() is not [[noreturn]]
>>   }
>>
>> This is almost certainly a bug; foo() was supposed to return something,
>> but didn't, which will lead to UB when foo() is called. Unfortunately,
>> while there exists a warning for this in some compilers, it is not
>> enabled by default.
>>
>> I have a difficult time thinking of a case where code like this is
>> intentional.
>>
>> I'd like to propose that the language be changed such that falling off
>> the end of a non-void function (i.e. that the compiler can detect that
>> this legitimately occurs) is ill-formed, unless (a) an annotation
>> expressing that intent is present, or (b) the compiler detects that the
>> return value is initialized by some other means (e.g. inline assembly).
>> The intent is that such functions would raise a compile *error*.
>>
>> This does not change any ABI, so already compiled code would continue to
>> work. I would further encourage recommending that compilers provide a
>> mode switch to disable this behavior in case old, broken code needs to
>> be compiled.
>>
>> What do folks think?
>
>
> Consider:
>
> enum E { a, b, c };
> int f(E e) {
>   switch (e) {
>   case a: return 1;
>   case b: return 2;
>   case c: return 3;
>   }
> }
>
> Should this be rejected? f might be legitimately called with e == (E)3. Some
> compilers look at this and say "well, it looks like you intend for e to only
> take values that are named enumerators of E here, so I will not warn on
> this".
>
> I strongly think we should leave this in the hands of compiler implementors
> and not try to mandate some diagnostics here.
>

Can we not add a specifier "restrict" such that a restricted enum is
one whose value set consists only of its enumerators?

    restrict enum E { a, b, c };

If a switch over such an enum misses a case, the code is ill-formed.
Conversely if all cases are present, the compiler is allowed to assume
that the cases cover all possibilities.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 29 Sep 2014 16:20:57 -0400
Raw View
On 2014-09-29 15:51, Thiago Macieira wrote:
> On Monday 29 September 2014 15:15:15 Matthew Woehlke wrote:
>> I'd like to propose that the language be changed such that falling off
>> the end of a non-void function (i.e. that the compiler can detect that
>> this legitimately occurs) is ill-formed, unless (a) an annotation
>> expressing that intent is present, or (b) the compiler detects that the
>> return value is initialized by some other means (e.g. inline assembly).
>> The intent is that such functions would raise a compile *error*.
>
> Would this be ill-formed:
>
> int foo(int x)
> {
>  if (x == 1)
>   return doOne();
>  else if (x == 2)
>   return doTwo();
> }

Er... yes? "Yes!", even. That code, exactly as written, clearly has
problems :-). I want the compiler to reject code like that.

If there were an assert that (x == 1 || x == 2), then no. (Also a good
reason to get the recent assert-related stuff sorted and into the
standard :-).)

IOW, if you want to write code like that, either tell the compiler
explicitly to trust you to know what you're doing, or to trust that
control can't fall off the end. (See also where I wrote about having a
standardized way to say 'this is (we hope) unreachable'.)

Even better would be to stick a call to abort() at the bottom :-) (or
throw an exception, or otherwise invoke a less undefined behavior).
Since you're off in UB land anyway, performance is probably not a
concern at this point...

I should also note that I build just about everything with
-Werror=return-type and have yet to see a single false positive (but
have caught *lots* of bugs!). I submit that as empirical evidence that
such code is rare to nonexistent "in the wild".

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 29 Sep 2014 16:34:25 -0400
Raw View
On 2014-09-29 15:52, Richard Smith wrote:
> Consider:
>
> enum E { a, b, c };
> int f(E e) {
>   switch (e) {
>   case a: return 1;
>   case b: return 2;
>   case c: return 3;
>   }
> }
>
> Should this be rejected?

That's a reasonable question. I honestly could go either way with that
specific example. For what it's worth, gcc does issue a (-Wreturn-type)
diagnostic on this code.

> I strongly think we should leave this in the hands of compiler implementors
> and not try to mandate some diagnostics here.

My original wording attempts to imply that a compiler can still be
conforming if it will never issue this diagnostic. The point is to
*allow* (and strongly encourage) compilers to flag missing 'return' as
an error, which currently is not permitted.

Along with that, it should go without saying that compilers should err
on the side of tolerance if a case appears overly ambiguous.

That said, this is a clear case where some mechanism to tell the
compiler 'e had better really be a member of E' would be useful.



I'd still be ecstatic if the only cases that are flagged are those where
there exists a control path that executes code and then runs off the end
of the function. Such cases are almost sure to be bugs, and would catch
most of the problematic examples I've seen in the wild. Thus, even this
much would be a much welcomed improvement.

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 29 Sep 2014 16:49:42 -0400
Raw View
On 2014-09-29 16:37, Richard Smith wrote:
> On Mon, Sep 29, 2014 at 1:20 PM, Matthew Woehlke wrote:
>> I should also note that I build just about everything with
>> -Werror=return-type and have yet to see a single false positive (but
>> have caught *lots* of bugs!). I submit that as empirical evidence that
>> such code is rare to nonexistent "in the wild".
>
> Using which compiler? GCC's has a lot of false positives in my experience
> (primarily with switches over enums).

Using gcc.

Per my other reply, I'd be okay with this case not being flagged. (An
unfortunate number of the genuine errors I've seen involve functions
with no flow control statements *at all* :-(. Right now, as I
understand, the standard *forbids* disallowing that by default. That's
the behavior I consider especially unfortunate and would like to change.)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: gmisocpp@gmail.com
Date: Mon, 29 Sep 2014 14:08:47 -0700 (PDT)
Raw View
------=_Part_45_691308344.1412024928270
Content-Type: text/plain; charset=UTF-8



On Tuesday, September 30, 2014 8:52:05 AM UTC+13, Richard Smith wrote:
>
> On Mon, Sep 29, 2014 at 12:15 PM, Matthew Woehlke <
> mw_t...@users.sourceforge.net <javascript:>> wrote:
>
>> Right now, in C++ it is legal to write something like:
>>
>>   int foo()
>>   {
>>     bar(); // assume for now that bar() is not [[noreturn]]
>>   }
>>
>> This is almost certainly a bug; foo() was supposed to return something,
>> but didn't, which will lead to UB when foo() is called. Unfortunately,
>> while there exists a warning for this in some compilers, it is not
>> enabled by default.
>>
>> I have a difficult time thinking of a case where code like this is
>> intentional.
>>
>> I'd like to propose that the language be changed such that falling off
>> the end of a non-void function (i.e. that the compiler can detect that
>> this legitimately occurs) is ill-formed, unless (a) an annotation
>> expressing that intent is present, or (b) the compiler detects that the
>> return value is initialized by some other means (e.g. inline assembly).
>> The intent is that such functions would raise a compile *error*.
>>
>> This does not change any ABI, so already compiled code would continue to
>> work. I would further encourage recommending that compilers provide a
>> mode switch to disable this behavior in case old, broken code needs to
>> be compiled.
>>
>> What do folks think?
>>
>
> Consider:
>
> enum E { a, b, c };
> int f(E e) {
>   switch (e) {
>   case a: return 1;
>   case b: return 2;
>   case c: return 3;
>   }
> }
>
> Should this be rejected? f might be legitimately called with e == (E)3.
> Some compilers look at this and say "well, it looks like you intend for e
> to only take values that are named enumerators of E here, so I will not
> warn on this".
>
> I strongly think we should leave this in the hands of compiler
> implementors and not try to mandate some diagnostics here.
>

Hi Compiler Implementor!

I've been bitten by your example several times in the past, certainly by
gcc, but also by clang. I don't have an immediate clang example to give
you right now but, when I see one next time, I might forward it to you.

I think 'the right' attributes could cover many cases (ho ho ho), including
your example, it's just getting the right words that say no more or no
less, that's why I broadly agree that leaving it to compiler vendors is
probably right, but I still can't help thinking we can improve on the
situation.

On that basis, let's take your challenge. It's worth the effort, hopefully
others will follow suit and get it right:

Why not this:

enum E { a, b, c };
int f(E e) {
  switch (e) [[switch_on_all_enum_values]] (E) {
  case a: return 1;
  case b: return 2;
  case c: return 3;
  }
}

This attribute is highly specific, it says 'this switch is supposed to
cover all enum values' if it doesn't, it's an warning/error.
The compiler can complain if any enum is missing. That also feeds into the
can return theorization logic too for this example.
I believe something like this would cover a lot of use cases and solve your
example, and be generally useful in the OP's scenario.
It would be an improvement on the status quo.

I'm sure it's a mine field and there are plenty of cases where we can't
catch, but any small steps we can make here would be nice.

Perhaps there are other alternatives like:

enum E { a, b, c };
int f(E e) {
  switch (e) [[switch_on_all_enum_values]] (E) {
  case a: return 1;
  case b: return 2;
  case c: return 3;
  }
}

noreturn { // Whatever happens in here, there must be no way out.
   app_exit();
}

// compiler generates something like this, if it can't verify the noreturn
block always exits.
// i.e. tries to check app_exit() is [[noreturn]] etc. or whatever.
try
{
  app_exit();
}
catch(...)
{
    std::terminate();
}

Anyway, you get the idea. Both these tools could be useful independently
and together.

Surely there is something we can do to improve things here though things
are getting a lot better.

Ok, pull it apart. :)

Thanks

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_45_691308344.1412024928270
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, September 30, 2014 8:52:05 AM UTC+13, =
Richard Smith wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px =
0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); bo=
rder-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div><div=
 class=3D"gmail_quote">On Mon, Sep 29, 2014 at 12:15 PM, Matthew Woehlke <s=
pan dir=3D"ltr">&lt;<a onmousedown=3D"this.href=3D'javascript:';return true=
;" onclick=3D"this.href=3D'javascript:';return true;" href=3D"javascript:" =
target=3D"_blank" gdf-obfuscated-mailto=3D"NasoD73p3oYJ">mw_t...@users.sour=
ceforge.<wbr>net</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: =
rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">Righ=
t now, in C++ it is legal to write something like:<br>
<br>
&nbsp; int foo()<br>
&nbsp; {<br>
&nbsp; &nbsp; bar(); // assume for now that bar() is not [[noreturn]]<br>
&nbsp; }<br>
<br>
This is almost certainly a bug; foo() was supposed to return something,<br>
but didn't, which will lead to UB when foo() is called. Unfortunately,<br>
while there exists a warning for this in some compilers, it is not<br>
enabled by default.<br>
<br>
I have a difficult time thinking of a case where code like this is<br>
intentional.<br>
<br>
I'd like to propose that the language be changed such that falling off<br>
the end of a non-void function (i.e. that the compiler can detect that<br>
this legitimately occurs) is ill-formed, unless (a) an annotation<br>
expressing that intent is present, or (b) the compiler detects that the<br>
return value is initialized by some other means (e.g. inline assembly).<br>
The intent is that such functions would raise a compile *error*.<br>
<br>
This does not change any ABI, so already compiled code would continue to<br=
>
work. I would further encourage recommending that compilers provide a<br>
mode switch to disable this behavior in case old, broken code needs to<br>
be compiled.<br>
<br>
What do folks think?<br></blockquote><div><br></div><div>Consider:</div><di=
v><br></div><div>enum E { a, b, c };</div><div>int f(E e) {</div><div>&nbsp=
; switch (e) {</div><div>&nbsp; case a: return 1;</div><div>&nbsp; case b: =
return 2;</div><div>&nbsp; case c: return 3;</div><div>&nbsp; }</div><div>}=
</div><div>&nbsp;</div><div>Should this be rejected? f might be legitimatel=
y called with e =3D=3D (E)3. Some compilers look at this and say "well, it =
looks like you intend for e to only take values that are named enumerators =
of E here, so I will not warn on this".</div><div><br></div><div>I strongly=
 think we should leave this in the hands of compiler implementors and not t=
ry to mandate some diagnostics here.</div></div></div></div></blockquote><d=
iv><br></div><div>Hi Compiler Implementor!</div><div><br></div><div>I've be=
en bitten by your example several times in the past, certainly by gcc, but =
also by clang. I don't have an immediate clang example to give you&nbsp;rig=
ht now but, when I see one next time, I might forward it to you.</div><div>=
<br></div><div>I think 'the right' attributes could cover many cases (ho ho=
 ho), including your example, it's just getting the right words that say no=
 more or no less, that's why I broadly agree that leaving it to compiler ve=
ndors is probably right, but I still can't help thinking we can improve on =
the situation.</div><div><br></div><div>On that basis, let's take your chal=
lenge. It's worth the effort, hopefully others will follow suit and get it =
right:</div><div><br></div><div>Why not this:</div><div><br></div><div><div=
>enum E { a, b, c };</div><div>int f(E e) {</div><div>&nbsp; switch (e) [[s=
witch_on_all_enum_values]] (E) {</div><div>&nbsp; case a: return 1;</div><d=
iv>&nbsp; case b: return 2;</div><div>&nbsp; case c: return 3;</div><div>&n=
bsp; }</div><div>}</div><div>&nbsp;</div><div>This attribute is highly spec=
ific, it says 'this switch is supposed to cover all enum values' if it does=
n't, it's an warning/error.</div><div>The compiler can complain if&nbsp;any=
&nbsp;enum is missing.&nbsp;That also feeds into the can return theorizatio=
n logic too for this example.</div><div>I believe something like this would=
 cover a lot of use cases and solve your example, and&nbsp;be generally use=
ful in the OP's scenario.</div><div>It would be an improvement on the statu=
s quo.</div><div><br></div><div>I'm sure it's a mine field and there are pl=
enty of cases where we can't catch, but any small steps we can make here wo=
uld be nice.</div><div><br></div><div>Perhaps there are other alternatives =
like:</div><div><br></div><div><div>enum E { a, b, c };</div><div>int f(E e=
) {</div><div>&nbsp; switch (e) [[switch_on_all_enum_values]] (E) {</div><d=
iv>&nbsp; case a: return 1;</div><div>&nbsp; case b: return 2;</div><div>&n=
bsp; case c: return 3;</div><div>&nbsp; }</div><div>}</div><div><br></div><=
div>noreturn&nbsp;{ // Whatever happens in here, there must be no way out.<=
/div><div>&nbsp;&nbsp; app_exit();</div><div>}</div><div><br></div><div>// =
compiler generates something like this, if it can't verify the noreturn blo=
ck always exits.</div><div>// i.e. tries to check app_exit() is [[noreturn]=
] etc. or whatever.</div><div>try<br>{</div><div>&nbsp;&nbsp;app_exit();</d=
iv><div>}</div><div>catch(...)</div><div>{</div><div>&nbsp;&nbsp;&nbsp; std=
::terminate();<br>}&nbsp; </div><div>&nbsp;</div><div>Anyway, you get the i=
dea. Both these tools could be useful independently and together.</div><div=
><br></div><div>Surely there is something we can do to improve things here =
though things are getting a lot better.</div><div><br></div><div>Ok, pull i=
t apart. :)</div><div><div><br></div><div>Thanks</div></div></div></div></d=
iv>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_45_691308344.1412024928270--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 30 Sep 2014 13:28:07 -0400
Raw View
On 2014-09-29 17:11, Thiago Macieira wrote:
> On Monday 29 September 2014 16:20:57 Matthew Woehlke wrote:
>>> int foo(int x)
>>> {
>>>       if (x == 1)
>>>               return doOne();
>>>       else if (x == 2)
>>>               return doTwo();
>>> }
>>
>> [snip] if you want to write code like that, either tell the compiler
>> explicitly to trust you to know what you're doing, or to trust that
>> control can't fall off the end.
>
> Oh, I definitely wouldn't write the code above as-is. I'd have written it as:
>
> int foo(int x) noexcept
> {
>         if (x == 1)
>                 return doOne();
>         else if (x == 2)
>                 return doTwo();
>  Q_UNREACHABLE();
> }
>
> Q_UNREACHABLE() expands to __builtin_unreachable() for GCC and Clang;
> __assume(false) for ICC and MSVC. So that does what I wanted.

Ah! So you *have* told the compiler that program flow will never get
there. Then there is no issue with your example; indeed, if the
diagnostic were to trigger, it would be a blatant compiler bug.

(And again, I would also *strongly* encourage compiler vendors to
provide a non-annotation means to suppress the diagnostic, which could
be used as a work-around in case of such bugs.)

> Of course, it expands to absolutely nothing on other compilers (it actually
> expands to Q_ASSERT_X(false, "Q_UNREACHABLE was reached"), which in release
> mode expands to nothing).
>
> If you want to make the code above ill-formed, please give me a standardised
> "this is unreachable" marker which is guaranteed to expand to zero code.

Right; as I said previously, this does more or less need to go in either
with or after standardized unreachability and/or improvements to assert
(noting that 'unreachable' can - and possibly *should* - be written
'assert(false)'). Although I'll also point out that this is somewhat
more of a vendor issue; since the intent is that the compiler is not
strictly *required* to perform this form of analysis, it stands to
reason that vendors would not add the diagnostic unless they feel
comfortable that developers can properly instrument their code to inform
the compiler of cases like the above example.

FYI: I also want to make clear that I am in no way proposing silent code
injection. My intent is only in diagnosing problematic code at compile
time. (I don't count instrumenting such code with the addition of e.g.
assert in that statement, but of course that's not *silent*; first,
there is clearly an assert in the source, and second, I would expect
that the assert has no effect besides optimization anyway in release mode.)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.