Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Silly undead code.

45 views
Skip to first unread message

Alf P. Steinbach

unread,
Feb 24, 2017, 11:03:12 PM2/24/17
to
It just occurred to me that an `if(false) STM` does not always make the
complete STM dead code:


#include <iostream>
using namespace std;

auto main() -> int
{
int const n = 7;
switch( n )
{
case 1: cout << "one!\n"; break;
if( false )
{
case 7: cout << "seven!\n"; break;
}
default: cout << "Switch default.\n";
}
}


It also occurred to me that I don't know that standard's rules that make
this case work as unexpected, but makes the code invalid when the `if`
is replaced with a `while` or `switch`.

Hm.


Cheers!,

- Alf

Alf P. Steinbach

unread,
Feb 25, 2017, 12:44:23 AM2/25/17
to
On 25.02.2017 05:37, Stefan Ram wrote:
> "Alf P. Steinbach" <alf.p.stein...@gmail.com> writes:
>> It also occurred to me that I don't know that standard's rules that make
>> this case work as unexpected, but makes the code invalid when the `if`
>> is replaced with a `while` or `switch`.
>
> By »invalid«, you might mean that »seven!« will /not/ be
> printed in the case of a »while«. I believe that the
> standard requires the »while« to behave like the »if«,
> and when »seven!« is not printed, it's an error in the
> C++ implementation.
>
> A nested »switch«, however, clearly starts a new scope
> for case-lables, so it is correct, when »seven!« is not
> printed in this case.
>

Oh, it seems you're right. It looks like a compiler bug. With g++
replacing `if` with `while` makes the "seven!" output disappear:


[example]
[C:\my\temp]
> type undead.cpp
#include <iostream>
using namespace std;

auto main() -> int
{
int const n = 7;
switch( n )
{
case 1: cout << "one!\n"; break;
while( false )
{
case 7: cout << "seven!\n"; break;
}
default: cout << "Switch default.\n";
}
}

[C:\my\temp]
> (g++ --version | find "++") && g++ undead.cpp && a
g++ (x86_64-win32-sjlj-rev1, Built by MinGW-W64 project) 6.3.0
Switch default.

[C:\my\temp]
> _
[/example]


With Visual C++ 2015 it's executed:


[example]
[C:\my\temp]
> (cl /nologo- 2>&1 | find "++") && cl undead.cpp /Feb && b
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86
undead.cpp
seven!
Switch default.

[C:\my\temp]
> _
[/example]


Still, with the compilers disagreeing it would be nice to know what the
standard says about this. I guess C++ /should/ behave like old C here
for backward compatibility, e.g. in order to make the old Duff's device
trick work. So it seems Visual C++ is right and g++ is buggy, but... :)

Cheers!,

- Alf

Öö Tiib

unread,
Feb 25, 2017, 9:57:24 AM2/25/17
to
On Saturday, 25 February 2017 07:44:23 UTC+2, Alf P. Steinbach wrote:
>
> Still, with the compilers disagreeing it would be nice to know what the
> standard says about this. I guess C++ /should/ behave like old C here
> for backward compatibility, e.g. in order to make the old Duff's device
> trick work. So it seems Visual C++ is right and g++ is buggy, but... :)

Yes, gcc seems to not work also with 'for(;0;)'.

Perhaps they have screwed up there something when they implemented
'__builtin_fallthrough' or some other thing like that.

Johann Klammer

unread,
Feb 28, 2017, 6:28:32 AM2/28/17
to
Geez, you must have been reading the yosys code, lately!
<https://github.com/cliffordwolf/yosys>
(in pretty much any switch)

also:
<http://www.clifford.at/cfun/cliffdev/>


0 new messages