Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #161795

Re: naked switches

From David Brown <david.brown@hesbynett.no>
Newsgroups comp.lang.c
Subject Re: naked switches
Date 2021-07-09 19:20 +0200
Organization A noiseless patient Spider
Message-ID <sca0gf$hud$1@dont-email.me> (permalink)
References (5 earlier) <sc7aeg$10u$1@dont-email.me> <sc8von$8fo$1@dont-email.me> <sc979l$n65$1@dont-email.me> <sc9jam$1ahh$1@gioia.aioe.org> <sc9oni$go9$1@dont-email.me>

Show all headers | View raw


On 09/07/2021 17:07, Bart wrote:
> On 09/07/2021 14:35, Manfred wrote:
>> On 7/9/2021 12:09 PM, Bart wrote:
>>> On 09/07/2021 09:01, David Brown wrote:
>>>> On 08/07/2021 18:51, Bart wrote:
>>>>> On 08/07/2021 16:52, David Brown wrote:
>> [...]
>>>>>    It is not something I have seen on other compilers, and I've used
>>>>>> quite a large number over the years for far smaller and slower
>>>>>> devices
>>>>>> than you are describing here.
>>>>>>
>>>>>> The way you handle this with gcc has already been covered - you use
>>>>>> __builtin_unreachable() to tell the compiler how to optimise for
>>>>>> "this
>>>>>> can't happen" cases.  clang supports __builtin_unreachable() too, and
>>>>>> MSVC has "__assume(false)" that has the same effect.
>>>>>>
>>>>>
>>>>> How would that work in that case? There doesn't appear to be a bit of
>>>>> code to hang that onto, unless you specifically create an empty block
>>>>> for the purpose, guarded by the same sort of range check you want
>>>>> to avoid.
>>>>
>>>> The normal situation would be :
>>>>
>>>>     switch (x) {
>>>>         case 1 : handle1(); break;
>>>>         case 2 : handle2(); break;
>>>>         case 4 : handle4(); break;
>>>>         default : __builtin_unreachable();    // gcc
>>>>         default : __assume(0);            // msvc
>>>>     }
>>>
>>> As I said, you may want to reserve default: for x==3.
>>>
>>>>
>>>>
>>>>
>>>> If you want to say x == 3 is a "do nothing" situation, but you want to
>>>> tell the compiler it doesn't need to check for x < 1 or x > 4, then you
>>>> do so simply and clearly:
>>>>
>>>>     if ((x < 1) || (x > 4)) __builtin_unreachable();    // gcc
>>>>     __assume((x >= 1) && (x <= 4));                // msvc
>>>
>>> This is really ugly and may involve some compilers (eg. mine) adding
>>> all those extra checks.
>>>
>>
>> __builtin_unreachable() is a GCC extension (and similarly __assume()
>> for msvc) that is supposed to have no meaning other than for GCC. And
>> that meaning is an instruction for the compiler to consider that range
>> for 'x' impossible to happen, and optimize accordingly - not to add
>> any extra check.
>> The fact that your compiler may interpret this instruction differently
>> is irrelevant because, well, this is a GCC-specific extension - in
>> fact your compiler should just /refuse/ to compile the code because
>> __builtin_unreachable() should be undefined in your implementation.
>>
>> Ugliness is an intentional feature of implementation-specific extensions.

That's not true, IME.  But avoiding any conceivable clash with otherwise
valid code is an intentional feature, hence double underscores are common.

> 
> Actually my attention was on the GCC extension. The MSVC version is not
> too bad, and would be similar to what I'd come up to give an hint about
> the values of a variable. (I'd use 'assume x in 1..4')
> 

Personally, I use a macro :


void __attribute__((error("Assume failed"))) assumeFailed(void);

// The compiler can assume that "x" is true, and optimise or warn
// accordingly
// If the compiler can see that the assume will fail, it gives an error
#define assume(x) \
                do { \
                        if (__builtin_constant_p(!(x))) { \
                                if (!(x)) { \
                                        assumeFailed(); \
                                } \
                        } \
                        if (!(x)) __builtin_unreachable(); \
                } while (0)


But in the context of a discussion like this, it usually makes sense to
write the feature out in its "raw" form, even if some people think it is
ugly.

> However both rather leave open what should be done with that
> information.

You are giving the compiler and any programmer reading the code a bit of
extra information.  How much the compiler can use it to optimise code is
up to the quality of the compiler, just like any other code.

> You have to hope a compiler will put it to some use in a
> subsequence switch(x) statement, but what happens if intervening code
> makes x less well-defined, such as ++x?

The compiler knows the assumptions you give it hold when they are given.
 If you increment x, it knows that now x >= 2 and x <= 5.  (Again, what
it can do with this information is a matter of quality of optimisation.)

> 
> Suppose the switch is switch (x-2)?
> 
> This is why a way of directly hinting at the behaviour of switch is
> preferable IMO. Then you /know/ what's going to happen.

No, you don't /know/ what is going to happen.  You would merely be
giving a hint, and it is up to the compiler to generate code that has
the same effect - as efficiently or inefficiently as it wants.  You
don't /know/ you'll get a jump table, or any other code generated from
the switch.  Why would you think you know about what might be generated
by a hint about "naked" switches?  The compiler guarantees observable
behaviour, not generated code.

> 
> There are other ways of doing this: instead of one 'default:' branch,
> there can be two, one executed for gaps in the range (of minimum to
> maximum case values), the other for values outside the range. This is
> where it would make more sense for an unreachable() attribute to go.
> 
> (I'm not going to propose C syntax for this. In my stuff, having two
> kinds of 'else', as it is there, is an intriguing idea. It can at least
> be used to trap out of range indices in a working program.)
> 

It is a silly idea, IMHO.  Either the value is valid or it is not.  I
see no benefits in trying to say that some values are more invalid than
others just because they are outside a certain range.

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

naked switches Robert Finch <robfi680@gmail.com> - 2021-07-07 16:39 -0700
  Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 01:26 +0100
  Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 01:57 +0000
    Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-08 09:16 +0200
  Re: naked switches Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-07-08 01:00 -0700
    Re: naked switches Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-07-08 03:25 -0700
      Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 06:58 -0700
        Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 15:52 +0100
        Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-08 17:52 +0200
          Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 17:51 +0100
            Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:01 +0200
              Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 11:09 +0100
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 13:14 +0200
                Re: naked switches Manfred <noname@add.invalid> - 2021-07-09 15:35 +0200
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 16:51 +0200
                Re: naked switches Manfred <noname@add.invalid> - 2021-07-09 18:23 +0200
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 16:07 +0100
                Re: naked switches Manfred <noname@add.invalid> - 2021-07-09 18:41 +0200
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 11:02 +0200
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 19:20 +0200
                Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-09 10:46 -0700
                Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-09 19:56 +0000
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 22:01 +0100
                Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-09 15:07 -0700
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 23:30 +0100
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 12:17 +0200
          Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 10:18 -0700
            Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 18:43 +0100
              Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 15:32 -0700
            Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 17:47 +0000
              Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 15:45 -0700
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:27 +0200
                Re: naked switches Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-07-09 11:13 +0100
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 13:30 +0200
                Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-11 00:39 -0700
                Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-11 14:06 +0000
                Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-11 08:01 -0700
                Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-16 03:53 -0700
                Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-16 14:47 +0000
                Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-09-30 06:09 -0700
                Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-09-30 07:03 -0700
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 13:44 +0100
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 13:28 +0200
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-10 13:04 +0100
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 15:39 +0200
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-10 15:08 +0100
                Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 17:34 +0200
                Re: naked switches Bart <bc@freeuk.com> - 2021-07-10 17:47 +0100
              Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-11 00:57 -0700
                Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-16 03:51 -0700
        Re: naked switches Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-07-08 11:40 -0700
          Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:38 +0200
  Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 17:33 +0000
    Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-08 17:47 +0000
      Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 17:58 +0000
        Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-08 19:13 +0000
          Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-09 02:30 +0000
        Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:41 +0200
  Re: naked switches Bonita Montero <Bonita.Montero@gmail.com> - 2021-09-30 18:04 +0200

csiph-web