Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

"Besides, I think [Slackware] sounds better than 'Microsoft,' don't you?" (By Patrick Volkerding)


devel / comp.lang.c / Re: naked switches

SubjectAuthor
* naked switchesRobert Finch
+- Re: naked switchesBart
+* Re: naked switchesKaz Kylheku
|`- Re: naked switchesDavid Brown
+* Re: naked switchesKeith Thompson
|`* Re: naked switchesMalcolm McLean
| `* Re: naked switchesRobert Finch
|  +- Re: naked switchesBart
|  +* Re: naked switchesDavid Brown
|  |+* Re: naked switchesBart
|  ||`* Re: naked switchesDavid Brown
|  || `* Re: naked switchesBart
|  ||  +- Re: naked switchesDavid Brown
|  ||  `* Re: naked switchesManfred
|  ||   +* Re: naked switchesDavid Brown
|  ||   |`- Re: naked switchesManfred
|  ||   `* Re: naked switchesBart
|  ||    +* Re: naked switchesManfred
|  ||    |`- Re: naked switchesDavid Brown
|  ||    `* Re: naked switchesDavid Brown
|  ||     `* Re: naked switchesRobert Finch
|  ||      +- Re: naked switchesKaz Kylheku
|  ||      +* Re: naked switchesBart
|  ||      |`* Re: naked switchesRobert Finch
|  ||      | `- Re: naked switchesBart
|  ||      `- Re: naked switchesDavid Brown
|  |`* Re: naked switchesRobert Finch
|  | +* Re: naked switchesBart
|  | |`- Re: naked switchesRobert Finch
|  | `* Re: naked switchesKaz Kylheku
|  |  +* Re: naked switchesRobert Finch
|  |  |`* Re: naked switchesDavid Brown
|  |  | +* Re: naked switchesBen Bacarisse
|  |  | |+- Re: naked switchesDavid Brown
|  |  | |`* Re: naked switchesTim Rentsch
|  |  | | `* Re: naked switchesScott Lurndal
|  |  | |  +- Re: naked switchesRobert Finch
|  |  | |  `* Re: naked switchesTim Rentsch
|  |  | |   `* Re: naked switchesScott Lurndal
|  |  | |    `* Re: naked switchesTim Rentsch
|  |  | |     `- Re: naked switchesRobert Finch
|  |  | `* Re: naked switchesBart
|  |  |  `* Re: naked switchesDavid Brown
|  |  |   `* Re: naked switchesBart
|  |  |    `* Re: naked switchesDavid Brown
|  |  |     `* Re: naked switchesBart
|  |  |      `* Re: naked switchesDavid Brown
|  |  |       `- Re: naked switchesBart
|  |  `* Re: naked switchesTim Rentsch
|  |   `- Re: naked switchesTim Rentsch
|  `* Re: naked switchesKeith Thompson
|   `- Re: naked switchesDavid Brown
+* Re: naked switchesKaz Kylheku
|`* Re: naked switchesScott Lurndal
| `* Re: naked switchesKaz Kylheku
|  +* Re: naked switchesScott Lurndal
|  |`- Re: naked switchesKaz Kylheku
|  `- Re: naked switchesDavid Brown
+- Re: naked switchesStefan Ram
`- Re: naked switchesBonita Montero

Pages:123
Re: naked switches

<sc9239$l99$2@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17363&group=comp.lang.c#17363

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 10:41:13 +0200
Organization: A noiseless patient Spider
Lines: 32
Message-ID: <sc9239$l99$2@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<20210708101340.323@kylheku.com> <QSGFI.7387$qk6.4293@fx36.iad>
<20210708105401.685@kylheku.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 9 Jul 2021 08:41:14 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="7ff94317d495bb646f4ebc938aee1ba8";
logging-data="21801"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ubOUAlReElUtlQ6vDCl2j6+dYdMAp4to="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:P8jQYg8qvk+KvwnGq/Vd5/oMplo=
In-Reply-To: <20210708105401.685@kylheku.com>
Content-Language: en-GB
 by: David Brown - Fri, 9 Jul 2021 08:41 UTC

On 08/07/2021 19:58, Kaz Kylheku wrote:
> On 2021-07-08, Scott Lurndal <scott@slp53.sl.home> wrote:
>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>> On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote:
>>>> I have been working on a C/C++ like compiler. One feature supported in
>>>> the compiler is naked switches. A naked switch omits the range
>>>> checking code that is normally associated with the switch statement.
>>>> Omitting this code can improve performance at the risk of a crash if
>>>> invalid cases are processed. I am wondering if there is a similar
>>>> option in other C compilers? Or would this just be an automatic
>>>> optimization at high levels?
>>>
>>> GNU C has the feature that labels can be treated as data; they
>>> can be stored in variables/objects and used to perform a goto.
>>
>> GCC generally generates optimal code sequences for switch
>> statements; from simple sequenced branches for small case
>> counts to jump tables for larger case counts.
>
> Elsewhere in the thread, I was not able to coax GCC into eliminating the
> range test and branch prior to the table switch, even if the default:
> case of the switch was __builtin_unreachable().
>
> Since two instructions can be removed form the code, it must not be
> optimal.
>

Did you try my suggestion of using a newer gcc? You can test it out on
<https://godbolt.org>.

gcc isn't perfect, and each new version adds new tweaks and
optimisations (and new features, and the occasional bug, regression, etc.).

Re: naked switches

<sc979l$n65$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17364&group=comp.lang.c#17364

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 11:09:55 +0100
Organization: A noiseless patient Spider
Lines: 140
Message-ID: <sc979l$n65$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <sc7aeg$10u$1@dont-email.me>
<sc8von$8fo$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Fri, 9 Jul 2021 10:09:57 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="17ac1ffb4847b1788192012d4b12bab9";
logging-data="23749"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX181gjGtlCG6/M2O4ZOx+7MSkg3I65wAadg="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:dozF1cecNuUrXjvCHg4mQJgvUew=
In-Reply-To: <sc8von$8fo$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210708-8, 8/7/2021), Outbound message
 by: Bart - Fri, 9 Jul 2021 10:09 UTC

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:
>>> On 08/07/2021 15:58, Robert Finch wrote:
>>>> On Thursday, July 8, 2021 at 6:25:26 AM UTC-4, Malcolm McLean wrote:
>>>>> On Thursday, 8 July 2021 at 09:00:40 UTC+1, Keith Thompson wrote:
>>>>>> Robert Finch <robf...@gmail.com> writes:
>>>>>>> I have been working on a C/C++ like compiler. One feature
>>>>>>> supported in
>>>>>>> the compiler is naked switches. A naked switch omits the range
>>>>>>> checking code that is normally associated with the switch
>>>>>>> statement. Omitting this code can improve performance at the risk
>>>>>>> of a
>>>>>>> crash if invalid cases are processed. I am wondering if there is a
>>>>>>> similar option in other C compilers? Or would this just be an
>>>>>>> automatic optimization at high levels?
>>>
>>>
>>>>
>>>> That is basically how it is working. There is still a default
>>>> statement for unimplemented values between the min and max. The table
>>>> entry may as well point somewhere useful. There were two goals with
>>>> this, a) a performance optimization and b) code size optimization. I
>>>> am dealing with small roms in an FPGA so bytes count. The processor
>>>> is also rather slow <40MHz.
>>>>
>>>>
>>>
>>> You wrote that you "have been working on a C/C++ like compiler" - do you
>>> mean you have been /using/ such a compiler, or you have been /writing/
>>> such a compiler?
>>>
>>> As I mentioned earlier, I think a "naked switch" like this is a terrible
>>> idea.
>>
>> I've considered having something like that. I'd have called it 'uswitch'.
>>
>> It was never done because:
>>
>> * The range check wasn't really much of an overhead on x64 (the indexed
>> jump is)
>>
>> * I could never be sure that the switch index would always be inside the
>> range of the minimum and maximum values of the switch cases
>>
>> * It seemed a bit naff
>>
>> But I wouldn't find it objectionable if it helps out on a slower
>> processor. After all array indices are not checked either as I said in
>> my last post.
>>
>
> The critical difference is the semantics of the C language - array
> indexes are not checked automatically in C, the range in a switch /is/
> checked because a switch is defined in the language to do nothing if the
> value does not match any of the cases.
>
> If you are making a different language, you can pick different rules.
>
> I've seen many compilers that have odd non-standard behaviour "to make C
> simpler" or "to get better code on this little processor". IME, it is
> /always/ a mistake. I've seen "const" used to mean "this is in flash",
> changes to the integer promotion rules, and other "improvements". The
> result is always mixups and misunderstandings, incompatibilities and
> people writing poorer code that is harder to follow, less portable /and/
> gives less efficient results on the smart-arse toolchain.
>
> If you are making a C compiler, make a /C/ compiler. If you want to get
> better results, make your optimisation smarter. If you want to give
> users something extra to squeeze a little more out of the target, give
> them something /useful/, /clear/, and /optional/. The answer here is
> __builtin_unreachable(), or __assume if you prefer MSVC's solution.
>
>>   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.

But also, how would this work in practice? Case values are usually
enums, you'd need to go and find which are the minimum and maximum
enums, and hope they don't change.

However, if you know that x is always going to have a value of one of
those enums, and all enum cases are checked (no gaps), then uswitch will
be safe.

Gaps could be allowed, except for the danger that the gaps could be at
either end (so for enums of 1,2,3,4,5, it may omit 1 and/or 5, but it
will then assume 2-5 or 1-4).

>
> switch (x) {
> case 1 : handle1(); break;
> case 2 : handle2(); break;
> case 4 : handle4(); break;
> }
>
>
> Compare that to someone looking at "uswitch" and wondering what that
> might possibly mean,

Unchecked or unsafe. But no worse than scratching their head over
__builtin_unreachable and wondering what it has to do with that switch
further down the function.

Re: naked switches

<87czrr3ics.fsf@bsb.me.uk>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17365&group=comp.lang.c#17365

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: ben.use...@bsb.me.uk (Ben Bacarisse)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 09 Jul 2021 11:13:39 +0100
Organization: A noiseless patient Spider
Lines: 22
Message-ID: <87czrr3ics.fsf@bsb.me.uk>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="7981e5c6acbe731380f3e1626e9b60df";
logging-data="18608"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18xXJGBiXpL23KkD5outhAvLf3jbOtsbLI="
Cancel-Lock: sha1:M1s71C1wNUYUTEHb3ZRyLvtFiZ8=
sha1:2kaMBksafsbbM6xtrpy1676KdSM=
X-BSB-Auth: 1.c518f800fa4b54d65b3f.20210709111339BST.87czrr3ics.fsf@bsb.me.uk
 by: Ben Bacarisse - Fri, 9 Jul 2021 10:13 UTC

David Brown <david.brown@hesbynett.no> writes:

> Your extension [for extracting contiguous bits from a word] is not
> commonly used, because it only exists in your tool. People who need
> to do a lot of bit slicing and don't like masking and shifting (or
> struct bit-fields) should not have trouble defining:
>
> #define BIT(x, top, bottom) \
> (((x) >> (bottom)) & ((1llu << ((top) - (bottom) + 1)) - 1))
>
> Yes, the parenthesis you need for macros are ugly, but you only need to
> get it right once, and now you can read your bit-fields.

That's undefined when all the bits are wanted. (The left shift of 1llu
could be equal to the width.) Maybe you wrote it for a compiler that
documents an extension.

I usually right shift -1llu by the width minus the number of bits
wanted, but you can also just do two left shifts.

--
Ben.

Re: naked switches

<sc9b35$g6s$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17366&group=comp.lang.c#17366

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 13:14:45 +0200
Organization: A noiseless patient Spider
Lines: 189
Message-ID: <sc9b35$g6s$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <sc7aeg$10u$1@dont-email.me>
<sc8von$8fo$1@dont-email.me> <sc979l$n65$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Fri, 9 Jul 2021 11:14:46 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="7ff94317d495bb646f4ebc938aee1ba8";
logging-data="16604"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+cVYBc6W2DCqIG9M/PejOz1YqEoOdS9V8="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:V6e1F2MTiMZTyg+/O+3DaVOwmg0=
In-Reply-To: <sc979l$n65$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Fri, 9 Jul 2021 11:14 UTC

On 09/07/2021 12:09, 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:
>>>> On 08/07/2021 15:58, Robert Finch wrote:
>>>>> On Thursday, July 8, 2021 at 6:25:26 AM UTC-4, Malcolm McLean wrote:
>>>>>> On Thursday, 8 July 2021 at 09:00:40 UTC+1, Keith Thompson wrote:
>>>>>>> Robert Finch <robf...@gmail.com> writes:
>>>>>>>> I have been working on a C/C++ like compiler. One feature
>>>>>>>> supported in
>>>>>>>> the compiler is naked switches. A naked switch omits the range
>>>>>>>> checking code that is normally associated with the switch
>>>>>>>> statement. Omitting this code can improve performance at the risk
>>>>>>>> of a
>>>>>>>> crash if invalid cases are processed. I am wondering if there is a
>>>>>>>> similar option in other C compilers? Or would this just be an
>>>>>>>> automatic optimization at high levels?
>>>>
>>>>
>>>>>
>>>>> That is basically how it is working. There is still a default
>>>>> statement for unimplemented values between the min and max. The table
>>>>> entry may as well point somewhere useful. There were two goals with
>>>>> this, a) a performance optimization and b) code size optimization. I
>>>>> am dealing with small roms in an FPGA so bytes count. The processor
>>>>> is also rather slow <40MHz.
>>>>>
>>>>>
>>>>
>>>> You wrote that you "have been working on a C/C++ like compiler" - do
>>>> you
>>>> mean you have been /using/ such a compiler, or you have been /writing/
>>>> such a compiler?
>>>>
>>>> As I mentioned earlier, I think a "naked switch" like this is a
>>>> terrible
>>>> idea.
>>>
>>> I've considered having something like that. I'd have called it
>>> 'uswitch'.
>>>
>>> It was never done because:
>>>
>>> * The range check wasn't really much of an overhead on x64 (the indexed
>>> jump is)
>>>
>>> * I could never be sure that the switch index would always be inside the
>>> range of the minimum and maximum values of the switch cases
>>>
>>> * It seemed a bit naff
>>>
>>> But I wouldn't find it objectionable if it helps out on a slower
>>> processor. After all array indices are not checked either as I said in
>>> my last post.
>>>
>>
>> The critical difference is the semantics of the C language - array
>> indexes are not checked automatically in C, the range in a switch /is/
>> checked because a switch is defined in the language to do nothing if the
>> value does not match any of the cases.
>>
>> If you are making a different language, you can pick different rules.
>>
>> I've seen many compilers that have odd non-standard behaviour "to make C
>> simpler" or "to get better code on this little processor".  IME, it is
>> /always/ a mistake.  I've seen "const" used to mean "this is in flash",
>> changes to the integer promotion rules, and other "improvements".  The
>> result is always mixups and misunderstandings, incompatibilities and
>> people writing poorer code that is harder to follow, less portable /and/
>> gives less efficient results on the smart-arse toolchain.
>>
>> If you are making a C compiler, make a /C/ compiler.  If you want to get
>> better results, make your optimisation smarter.  If you want to give
>> users something extra to squeeze a little more out of the target, give
>> them something /useful/, /clear/, and /optional/.  The answer here is
>> __builtin_unreachable(), or __assume if you prefer MSVC's solution.
>>
>>>    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.

See below.

>
>>
>>
>>
>> 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.

I am not overly interested in such limited compilers. It is silly to
worry about the cost of an extra comparison or two in a normal switch
for a compiler (or compiler options) that can't even eliminate such
extra comparisons.

If you think the double underlines are ugly (and I won't disagree), use
a macro to give it a nicer name. Extensions are given such names to
avoid conflicts with valid user code. (Okay, it's unlikely that someone
would use "builtin_unreachable" as an identifier - but they certainly
could use "assume" or other short and neat alternatives.)

>
> But also, how would this work in practice? Case values are usually
> enums, you'd need to go and find which are the minimum and maximum
> enums, and hope they don't change.

You would not do that - because it would be a silly thing to do! There
really is no use-case for saying "This variable should be one of these
following values. If it is not, but it lies between the smallest and
the largest of these cases, then do nothing. But if it is outside that
range, do whatever you want." In reality, when you have a switch for an
enumeration type, you either want clear guaranteed behaviour for
unspecified cases (i.e., a "default" clause or "do nothing), or you are
confident that you will never run that code with an invalid enumeration
value, in which case "default : __builtin_unreachable();" is your answer.

Then it is up to the compiler to figure out how to handle the switch and
generate the best code - jump tables, calculations, if-then-else trees,
or whatever.

(A compiler warning for a switch of an enumeration type which does not
cover all enumeration values is a very useful help.)

>
> However, if you know that x is always going to have a value of one of
> those enums, and all enum cases are checked (no gaps), then uswitch will
> be safe.
>

True.

But "default : __builtin_unreachable();" is clearer, more flexible, more
portable, avoids an extra statement extension, and is a tool that can be
used in far more situations.

> Gaps could be allowed, except for the danger that the gaps could be at
> either end (so for enums of 1,2,3,4,5, it may omit 1 and/or 5, but it
> will then assume 2-5 or 1-4).
>
>>
>>     switch (x) {
>>         case 1 : handle1(); break;
>>         case 2 : handle2(); break;
>>         case 4 : handle4(); break;
>>     }
>>
>>
>> Compare that to someone looking at "uswitch" and wondering what that
>> might possibly mean,
>
>
> Unchecked or unsafe. But no worse than scratching their head over
> __builtin_unreachable and wondering what it has to do with that switch
> further down the function.
>


Click here to read the complete article
Re: naked switches

<sc9c05$m4k$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17367&group=comp.lang.c#17367

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 13:30:07 +0200
Organization: A noiseless patient Spider
Lines: 31
Message-ID: <sc9c05$m4k$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <87czrr3ics.fsf@bsb.me.uk>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 9 Jul 2021 11:30:13 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="7ff94317d495bb646f4ebc938aee1ba8";
logging-data="22676"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19nhmVCZKcqdSDqJCtO80F7Jh5FXwvR9jU="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:RgP9hF9F60JneXsOgQinSieEZDY=
In-Reply-To: <87czrr3ics.fsf@bsb.me.uk>
Content-Language: en-GB
 by: David Brown - Fri, 9 Jul 2021 11:30 UTC

On 09/07/2021 12:13, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> Your extension [for extracting contiguous bits from a word] is not
>> commonly used, because it only exists in your tool. People who need
>> to do a lot of bit slicing and don't like masking and shifting (or
>> struct bit-fields) should not have trouble defining:
>>
>> #define BIT(x, top, bottom) \
>> (((x) >> (bottom)) & ((1llu << ((top) - (bottom) + 1)) - 1))
>>
>> Yes, the parenthesis you need for macros are ugly, but you only need to
>> get it right once, and now you can read your bit-fields.
>
> That's undefined when all the bits are wanted. (The left shift of 1llu
> could be equal to the width.) Maybe you wrote it for a compiler that
> documents an extension.
>
> I usually right shift -1llu by the width minus the number of bits
> wanted, but you can also just do two left shifts.
>

Yes, to cover all cases you could use:

(1llu << ((top) - (bottom)) << 1)

It has always struck me as a little odd that (x << 32) is undefined (for
32-bit integers), even for unsigned x. It's fine to be undefined for
signed types, but I'd have thought it should at least be
implementation-defined (for efficiency on different targets), rather
than undefined. But I guess that's the rules, like it or not.

Re: naked switches

<sc9gav$iln$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17368&group=comp.lang.c#17368

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 13:44:13 +0100
Organization: A noiseless patient Spider
Lines: 52
Message-ID: <sc9gav$iln$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 9 Jul 2021 12:44:15 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="17ac1ffb4847b1788192012d4b12bab9";
logging-data="19127"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Ex2RabdBUo4KsBQASEmd93JJ6YKEDLTk="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:M4qAaQxOa6XyAsk/+ZDPTUSUv0U=
In-Reply-To: <sc9190$h4g$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210708-8, 8/7/2021), Outbound message
 by: Bart - Fri, 9 Jul 2021 12:44 UTC

On 09/07/2021 09:27, David Brown wrote:
> On 09/07/2021 00:45, Robert Finch wrote:
>> On Thursday, July 8, 2021 at 1:47:12 PM UTC-4, Kaz Kylheku wrote:
>>> A macro can do this:
>>>
>>> a = BIT(b,10,1);
>>>
>>> and works everywhere. What you need is a typeof extension to make it
>>> work with different integer types while retaining efficiency, otherwise
>>> you're looking at making it assume 64 bit, or saddling it with a type
>>> name argument.
>>
>> One should not have to write macros for commonly used language elements.
>
> Your extension is not commonly used, because it only exists in your
> tool. People who need to do a lot of bit slicing and don't like masking
> and shifting (or struct bit-fields) should not have trouble defining:
>
> #define BIT(x, top, bottom) \
> (((x) >> (bottom)) & ((1llu << ((top) - (bottom) + 1)) - 1))
>
> Yes, the parenthesis you need for macros are ugly, but you only need to
> get it right once, and now you can read your bit-fields.
>
> Having said that, it is not at all unreasonable for an embedded compiler
> to ship with extra headers, which would be an excellent place to put
> macros like this for user convenience. It would be simpler and clearer
> to C programmers who are not used to your extensions. This is the
> technique used by other embedded compilers.
>
> I'm not saying the extension is not useful, or bad in itself - but I
> dislike adding extensions when it is perfectly possible to get the same
> results without changing the language.

Then there would have been no need for the [] indexing syntax either.
You'd just write:

GETINDEX(a, i)
SETINDEX(a, i, x)

instead of a[i] or a[i]=x. Except these need special headers to be
dragged in, and everyone would be using their own incompatible macros;
try mixing code from different sources.

> You need very good reasons for
> adding non-portable extensions.

Such a set of macros as you propose would also be non-portable unless
you included custom headers. And then you mix code that needs
BIT(a,10,1) with code that needs BIT(a,1,10).

You don't however seem to mind using GNU C extensions!

Re: naked switches

<sc9jam$1ahh$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17371&group=comp.lang.c#17371

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!ElFVPqY+TvFDjG0suNPrQQ.user.gioia.aioe.org.POSTED!not-for-mail
From: non...@add.invalid (Manfred)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 15:35:20 +0200
Organization: Aioe.org NNTP Server
Lines: 100
Message-ID: <sc9jam$1ahh$1@gioia.aioe.org>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <sc7aeg$10u$1@dont-email.me>
<sc8von$8fo$1@dont-email.me> <sc979l$n65$1@dont-email.me>
NNTP-Posting-Host: ElFVPqY+TvFDjG0suNPrQQ.user.gioia.aioe.org
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
 by: Manfred - Fri, 9 Jul 2021 13:35 UTC

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.

> But also, how would this work in practice? Case values are usually
> enums, you'd need to go and find which are the minimum and maximum
> enums, and hope they don't change.
>
> However, if you know that x is always going to have a value of one of
> those enums, and all enum cases are checked (no gaps), then uswitch will
> be safe.
>
> Gaps could be allowed, except for the danger that the gaps could be at
> either end (so for enums of 1,2,3,4,5, it may omit 1 and/or 5, but it
> will then assume 2-5 or 1-4).
>

Extensions of this kind, that go beyond the scope of the core language,
are not required to feature compact and elegant code - these are
requirements for the core language. I think it is OK to have to get
through some coding gymnastics if you want to interact with
implementation deepnesses of your specific compiler.
If you use them a lot in your current project, macros are the usual
solution of course.

>>
>>     switch (x) {
>>         case 1 : handle1(); break;
>>         case 2 : handle2(); break;
>>         case 4 : handle4(); break;
>>     }
>>
>>
>> Compare that to someone looking at "uswitch" and wondering what that
>> might possibly mean,
>
>
> Unchecked or unsafe. But no worse than scratching their head over
> __builtin_unreachable and wondering what it has to do with that switch
> further down the function.
>

The topic is about a customized variant of some language construct, for
which you need specific compiler support - whatever compiler you use,
you need to know it in detail, and __builtin_unreachable is part of the
game if you use GCC.

Re: naked switches

<sc9npu$9t3$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17375&group=comp.lang.c#17375

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 16:51:41 +0200
Organization: A noiseless patient Spider
Lines: 87
Message-ID: <sc9npu$9t3$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <sc7aeg$10u$1@dont-email.me>
<sc8von$8fo$1@dont-email.me> <sc979l$n65$1@dont-email.me>
<sc9jam$1ahh$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Fri, 9 Jul 2021 14:51:42 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="7ff94317d495bb646f4ebc938aee1ba8";
logging-data="10147"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+5dZ/uILAECSy9EfCz74cbOngr+HThYb8="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:egIrFLOJ1VA77MugQ/GAMF6oAY0=
In-Reply-To: <sc9jam$1ahh$1@gioia.aioe.org>
Content-Language: en-GB
 by: David Brown - Fri, 9 Jul 2021 14:51 UTC

On 09/07/2021 15: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.
>

Presumably a compiler that does not implement __builtin_unreachable() as
an extension will see it as a call to a function. If the compiler is
C90, rather than C99, then it will have to accept the code even though
the function is not declared, and it will treat it as a normal function
- thus it will include the range check on x, and a call to an external
function "__builtin_unreachable()". This is, of course, not remotely
close to what you want to happen.

If you are using features like this and want your code to be portable,
you want something like :

#ifdef __GNUC__
#define Unreachable() __builtin_unreachable()
#elif defined(_MSC_VER)
#define Unreachable() __assume(0)
#else
#define Unreachable()
#endif

Then use Unreachable() macro in your code.

(And if the compiler still generates the extra range checks, then stop
worrying about the insignificant inefficiencies in the switch statement,
as you are not using an optimising compiler.)

> Ugliness is an intentional feature of implementation-specific extensions.
>

Re: naked switches

<sc9oni$go9$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17376&group=comp.lang.c#17376

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 16:07:28 +0100
Organization: A noiseless patient Spider
Lines: 83
Message-ID: <sc9oni$go9$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <sc7aeg$10u$1@dont-email.me>
<sc8von$8fo$1@dont-email.me> <sc979l$n65$1@dont-email.me>
<sc9jam$1ahh$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Fri, 9 Jul 2021 15:07:31 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="17ac1ffb4847b1788192012d4b12bab9";
logging-data="17161"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+ub2evsYldPnX9crZHeKXFRkdoctB3nzM="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:cN05Cn+ZHpQtIcUqj9mCMzz3w+E=
In-Reply-To: <sc9jam$1ahh$1@gioia.aioe.org>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210709-0, 9/7/2021), Outbound message
 by: Bart - Fri, 9 Jul 2021 15:07 UTC

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.

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')

However both rather leave open what should be done with that
information. 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?

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.

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.)

Re: naked switches

<sc9t6i$1vbt$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17379&group=comp.lang.c#17379

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!ElFVPqY+TvFDjG0suNPrQQ.user.gioia.aioe.org.POSTED!not-for-mail
From: non...@add.invalid (Manfred)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 18:23:49 +0200
Organization: Aioe.org NNTP Server
Lines: 94
Message-ID: <sc9t6i$1vbt$1@gioia.aioe.org>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <sc7aeg$10u$1@dont-email.me>
<sc8von$8fo$1@dont-email.me> <sc979l$n65$1@dont-email.me>
<sc9jam$1ahh$1@gioia.aioe.org> <sc9npu$9t3$1@dont-email.me>
NNTP-Posting-Host: ElFVPqY+TvFDjG0suNPrQQ.user.gioia.aioe.org
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
 by: Manfred - Fri, 9 Jul 2021 16:23 UTC

On 7/9/2021 4:51 PM, David Brown wrote:
> On 09/07/2021 15: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.
>>
>
> Presumably a compiler that does not implement __builtin_unreachable() as
> an extension will see it as a call to a function. If the compiler is
> C90, rather than C99, then it will have to accept the code even though
> the function is not declared, and it will treat it as a normal function
> - thus it will include the range check on x, and a call to an external
> function "__builtin_unreachable()". This is, of course, not remotely
> close to what you want to happen.

The compiler may generate the call, but the linker is not going to
assemble an executable if the function does not exist. This still holds
in C90.

>
> If you are using features like this and want your code to be portable,
> you want something like :
>
> #ifdef __GNUC__
> #define Unreachable() __builtin_unreachable()
> #elif defined(_MSC_VER)
> #define Unreachable() __assume(0)
> #else
> #define Unreachable()
> #endif
>
> Then use Unreachable() macro in your code.
>
> (And if the compiler still generates the extra range checks, then stop
> worrying about the insignificant inefficiencies in the switch statement,
> as you are not using an optimising compiler.)
>
>
>> Ugliness is an intentional feature of implementation-specific extensions.
>>
>

Re: naked switches

<sc9u7b$i1i$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17380&group=comp.lang.c#17380

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!ElFVPqY+TvFDjG0suNPrQQ.user.gioia.aioe.org.POSTED!not-for-mail
From: non...@add.invalid (Manfred)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 18:41:17 +0200
Organization: Aioe.org NNTP Server
Lines: 103
Message-ID: <sc9u7b$i1i$1@gioia.aioe.org>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
NNTP-Posting-Host: ElFVPqY+TvFDjG0suNPrQQ.user.gioia.aioe.org
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
 by: Manfred - Fri, 9 Jul 2021 16:41 UTC

On 7/9/2021 5:07 PM, 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.
>
> 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')

Good point.

>
> However both rather leave open what should be done with that
> information. 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?

I guess the fact is that this kind of extensions are tightly coupled to
the internal mechanics of the compiler, and from this perspective
__builtin_unreachable() may be gcc's way of handling this scenario (I
trust David on this, I am just saying this apparent "oddity" is simply
explained by gcc's internals, which is something they don't have to
justify to anyone outside their own project)

>
> 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.
>
> 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.

Yes, but this would be impact the language at the syntax level.
Extensions should be kept orthogonal to the core language syntax rules
when possible, I think.

>
> (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.)
>
>

Re: naked switches

<sca0gf$hud$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17382&group=comp.lang.c#17382

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 19:20:15 +0200
Organization: A noiseless patient Spider
Lines: 138
Message-ID: <sca0gf$hud$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Fri, 9 Jul 2021 17:20:15 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="689a11d8b02c88968c6f2bc08b08e530";
logging-data="18381"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18pQ7/SGmQTcEjALDrhiOU5kdR9t78ZoUo="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:0lUww6W4p6q90/W6ABVOYo5xT7w=
In-Reply-To: <sc9oni$go9$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Fri, 9 Jul 2021 17:20 UTC

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.

Re: naked switches

<b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17383&group=comp.lang.c#17383

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a37:9cb:: with SMTP id 194mr5114014qkj.296.1625852795965;
Fri, 09 Jul 2021 10:46:35 -0700 (PDT)
X-Received: by 2002:a05:620a:16da:: with SMTP id a26mr18206446qkn.7.1625852795826;
Fri, 09 Jul 2021 10:46:35 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Fri, 9 Jul 2021 10:46:35 -0700 (PDT)
In-Reply-To: <sca0gf$hud$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2607:fea8:1de1:d400:c08b:abbb:dce:60d9;
posting-account=QId4bgoAAABV4s50talpu-qMcPp519Eb
NNTP-Posting-Host: 2607:fea8:1de1:d400:c08b:abbb:dce:60d9
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com> <255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com> <sc76v8$8ah$1@dont-email.me>
<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> <sca0gf$hud$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
Subject: Re: naked switches
From: robfi...@gmail.com (Robert Finch)
Injection-Date: Fri, 09 Jul 2021 17:46:35 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Robert Finch - Fri, 9 Jul 2021 17:46 UTC

Is there a syntax for one-hot switches, switches that are based around powers of two? I would like the
compiler to optimize for usage of the BBS branch-on-bit set instruction if possible.

Re: naked switches

<20210709124909.355@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17387&group=comp.lang.c#17387

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: 563-365-...@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 19:56:43 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 45
Message-ID: <20210709124909.355@kylheku.com>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
<sca0gf$hud$1@dont-email.me>
<b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
Injection-Date: Fri, 9 Jul 2021 19:56:43 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="ecabee45d7d2d905d26faa4521428a5e";
logging-data="30548"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18J5uH4tlyUj1BjiStZ1NlUjNYtAleKA+o="
User-Agent: slrn/1.0.3 (Linux)
Cancel-Lock: sha1:jChM3b1OZmPckuyg0Z9pO3CJG7w=
 by: Kaz Kylheku - Fri, 9 Jul 2021 19:56 UTC

On 2021-07-09, Robert Finch <robfi680@gmail.com> wrote:
> Is there a syntax for one-hot switches, switches that are based around
> powers of two? I would like the compiler to optimize for usage of the
> BBS branch-on-bit set instruction if possible.

No, there isn't; switching an integer value to cases labeled by constant
integer expressions is all there is.

You are probably looking at

#include <stdlib.h>

const char *sw(int x)
{ if (x & 1)
goto L1;
if (x & 2)
goto L2;
if (x & 4)
goto L4;
if (x & 8)
goto L8;
if (x & 16)
goto L16;
if (x & 32)
goto L32;

abort();

L1: return "one";
L2: return "two";
L4: return "four";
L8: return "eight";
L16: return "sixteen";
L32: return "thirty-two";
}

That might use "branch if bit set", if such a thing is available in the
target instruction set. There is every opportunity to use it since the
mask is a constant expression testing one bit.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

Re: naked switches

<scadfp$4du$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17388&group=comp.lang.c#17388

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 22:01:43 +0100
Organization: A noiseless patient Spider
Lines: 24
Message-ID: <scadfp$4du$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
<sca0gf$hud$1@dont-email.me>
<b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 9 Jul 2021 21:01:45 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="17ac1ffb4847b1788192012d4b12bab9";
logging-data="4542"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/u3pueZ/iJowKtFmtqR4iLk27EIXZShrg="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:IeHA3h/3KyauLM+IJK7bKw7LhpE=
In-Reply-To: <b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210709-8, 9/7/2021), Outbound message
 by: Bart - Fri, 9 Jul 2021 21:01 UTC

On 09/07/2021 18:46, Robert Finch wrote:
> Is there a syntax for one-hot switches, switches that are based around powers of two? I would like the
> compiler to optimize for usage of the BBS branch-on-bit set instruction if possible.
>

The purpose of a switch statement is to enumerate all the values you're
interested in. So here, you'd have cases for 1, 2, 4, 8, 16 and so on.
Then you'd leave to the compiler to implement that as best it can.

If there are too many, use a function (or an inliner based on some
instruction that tells you the position of first or last '1' bit), and
use the result as a conventional linear index (0, 1, 2, 3, 4 instead of
1, 2, 4, 8, 16).

(My own languages specifically use a jumptable for a switch. If it's not
suitable (table would be too large), it will say so. Then you can change
to a different statement - like switch, but a different keyword - which
is implemented as a sequence of tests.

But also, a too-small jumptable might be changed automatically to that
other statement, if it will be more efficient.)

Re: naked switches

<ecc9dfb2-851e-430d-a4aa-fa8c403d1800n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17391&group=comp.lang.c#17391

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:ac8:5d09:: with SMTP id f9mr19265852qtx.91.1625868427982;
Fri, 09 Jul 2021 15:07:07 -0700 (PDT)
X-Received: by 2002:a05:6214:4e2:: with SMTP id cl2mr16749377qvb.55.1625868427829;
Fri, 09 Jul 2021 15:07:07 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Fri, 9 Jul 2021 15:07:07 -0700 (PDT)
In-Reply-To: <scadfp$4du$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2607:fea8:1de1:d400:c08b:abbb:dce:60d9;
posting-account=QId4bgoAAABV4s50talpu-qMcPp519Eb
NNTP-Posting-Host: 2607:fea8:1de1:d400:c08b:abbb:dce:60d9
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com> <255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com> <sc76v8$8ah$1@dont-email.me>
<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>
<sca0gf$hud$1@dont-email.me> <b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
<scadfp$4du$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <ecc9dfb2-851e-430d-a4aa-fa8c403d1800n@googlegroups.com>
Subject: Re: naked switches
From: robfi...@gmail.com (Robert Finch)
Injection-Date: Fri, 09 Jul 2021 22:07:07 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Robert Finch - Fri, 9 Jul 2021 22:07 UTC

On Friday, July 9, 2021 at 5:01:56 PM UTC-4, Bart wrote:
> On 09/07/2021 18:46, Robert Finch wrote:
> > Is there a syntax for one-hot switches, switches that are based around powers of two? I would like the
> > compiler to optimize for usage of the BBS branch-on-bit set instruction if possible.
> >
> The purpose of a switch statement is to enumerate all the values you're
> interested in. So here, you'd have cases for 1, 2, 4, 8, 16 and so on.
> Then you'd leave to the compiler to implement that as best it can.
>
I figured it out. The compiler now just looks at all the case values to determine if it is possible to use
BBS or BBC. There is no need for a special syntax.

> (My own languages specifically use a jumptable for a switch. If it's not
> suitable (table would be too large), it will say so. Then you can change
> to a different statement - like switch, but a different keyword - which
> is implemented as a sequence of tests.
>
> But also, a too-small jumptable might be changed automatically to that
> other statement, if it will be more efficient.)

I put a maximum limit on the size of a jump table of 1,000,000 entries in case some sort of code
generator is generating the cases. The table must be at least 33% populated, or a series of testing
and branching will be used.
A tabular switch will not be used if there are fewer than 3 cases.

800 LOC for switch processing in the compiler now.

Re: naked switches

<scaimi$gnc$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17393&group=comp.lang.c#17393

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Fri, 9 Jul 2021 23:30:39 +0100
Organization: A noiseless patient Spider
Lines: 40
Message-ID: <scaimi$gnc$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
<sca0gf$hud$1@dont-email.me>
<b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
<scadfp$4du$1@dont-email.me>
<ecc9dfb2-851e-430d-a4aa-fa8c403d1800n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 9 Jul 2021 22:30:42 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="17132"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18uTO66+JdNVjTHVWOgaVMHFNybu42Bxak="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:IpRBifhG5awmEZseLmsumH9pFOc=
In-Reply-To: <ecc9dfb2-851e-430d-a4aa-fa8c403d1800n@googlegroups.com>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210709-8, 9/7/2021), Outbound message
 by: Bart - Fri, 9 Jul 2021 22:30 UTC

On 09/07/2021 23:07, Robert Finch wrote:
> On Friday, July 9, 2021 at 5:01:56 PM UTC-4, Bart wrote:
>> On 09/07/2021 18:46, Robert Finch wrote:
>>> Is there a syntax for one-hot switches, switches that are based around powers of two? I would like the
>>> compiler to optimize for usage of the BBS branch-on-bit set instruction if possible.
>>>
>> The purpose of a switch statement is to enumerate all the values you're
>> interested in. So here, you'd have cases for 1, 2, 4, 8, 16 and so on.
>> Then you'd leave to the compiler to implement that as best it can.
>>
> I figured it out. The compiler now just looks at all the case values to determine if it is possible to use
> BBS or BBC. There is no need for a special syntax.
>
>> (My own languages specifically use a jumptable for a switch. If it's not
>> suitable (table would be too large), it will say so. Then you can change
>> to a different statement - like switch, but a different keyword - which
>> is implemented as a sequence of tests.
>>
>> But also, a too-small jumptable might be changed automatically to that
>> other statement, if it will be more efficient.)
>
> I put a maximum limit on the size of a jump table of 1,000,000 entries in case some sort of code
> generator is generating the cases. The table must be at least 33% populated, or a series of testing
> and branching will be used.

I thought this was for a small device! A switch of 334K to 1000K case
labels is some switch statement, even if machine-generated. And also
quite a hefty function body of at least 1 million lines for 1M labels.

I use a limit of 1000 labels for a desktop x64 processor. (Above 1000,
other solutions might be better, such as tables of function pointers.)

Trying a switch of 500,000 cases, only Tiny C deals with it
effortlessly. Other compilers either complain, or take forever.

> A tabular switch will not be used if there are fewer than 3 cases.
>
> 800 LOC for switch processing in the compiler now.
>

Re: naked switches

<scbnmr$rej$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17400&group=comp.lang.c#17400

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 11:02:18 +0200
Organization: A noiseless patient Spider
Lines: 121
Message-ID: <scbnmr$rej$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
<sc9u7b$i1i$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 10 Jul 2021 09:02:19 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="199b2681e3d790bf87f77b24379e3e4a";
logging-data="28115"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18UtqCKvtdVx2vvJXSAEGO5j0w7lMxr1yA="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:Ky1mBvNXCt2IFtCqYb3wajyGclM=
In-Reply-To: <sc9u7b$i1i$1@gioia.aioe.org>
Content-Language: en-GB
 by: David Brown - Sat, 10 Jul 2021 09:02 UTC

On 09/07/2021 18:41, Manfred wrote:
> On 7/9/2021 5:07 PM, 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.
>>
>> 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')
>
> Good point.
>
>>
>> However both rather leave open what should be done with that
>> information. 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?
>
> I guess the fact is that this kind of extensions are tightly coupled to
> the internal mechanics of the compiler, and from this perspective
> __builtin_unreachable()  may be gcc's way of handling this scenario (I
> trust David on this, I am just saying this apparent "oddity" is simply
> explained by gcc's internals, which is something they don't have to
> justify to anyone outside their own project)
>

In gcc's internal tree representation of code, they have a node type for
"undefined behaviour", which is used in some passes to establish facts
about expressions and values, such as possible ranges for data, and it
is used to eliminate branches that lead nowhere (i.e., the compiler
assumes undefined behaviour can't happen, or that the programmer doesn't
care what happens if it does). __builtin_unreachable() translates
directly to this "undefined behaviour" node.

>>
>> 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.
>>
>> 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.
>
> Yes, but this would be impact the language at the syntax level.
> Extensions should be kept orthogonal to the core language syntax rules
> when possible, I think.

Agreed.

>
>>
>> (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.)
>>
>>
>

Re: naked switches

<scbs35$uhm$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17401&group=comp.lang.c#17401

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!news.nntp4.net!aioe.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 12:17:08 +0200
Organization: A noiseless patient Spider
Lines: 10
Message-ID: <scbs35$uhm$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me> <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>
<sca0gf$hud$1@dont-email.me>
<b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 10:17:09 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="199b2681e3d790bf87f77b24379e3e4a";
logging-data="31286"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/MJjMhAxhmNTRH3zCUcyaMNuqv3D9JNTY="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:jt32unReY8UfPf8rETc2nyq//IE=
In-Reply-To: <b34f9e99-bfce-4b2d-a01c-ba03037461c5n@googlegroups.com>
Content-Language: en-GB
 by: David Brown - Sat, 10 Jul 2021 10:17 UTC

On 09/07/2021 19:46, Robert Finch wrote:
> Is there a syntax for one-hot switches, switches that are based
> around powers of two? I would like the compiler to optimize for usage
> of the BBS branch-on-bit set instruction if possible.
>

Not in C, no - there is not really any need. (You get that kind of
thing in hardware design languages, as it is useful in programmable
logic and chip design).

Re: naked switches

<scc085$6h2$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17402&group=comp.lang.c#17402

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 13:28:04 +0200
Organization: A noiseless patient Spider
Lines: 92
Message-ID: <scc085$6h2$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <sc9gav$iln$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 10 Jul 2021 11:28:05 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="199b2681e3d790bf87f77b24379e3e4a";
logging-data="6690"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+JDzEDd2V+YZLzD9OXwZrNoh1rxuu+Os4="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:RhgC8TN14M3uAaVyyJlDKjZuxvU=
In-Reply-To: <sc9gav$iln$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Sat, 10 Jul 2021 11:28 UTC

On 09/07/2021 14:44, Bart wrote:
> On 09/07/2021 09:27, David Brown wrote:
>> On 09/07/2021 00:45, Robert Finch wrote:
>>> On Thursday, July 8, 2021 at 1:47:12 PM UTC-4, Kaz Kylheku wrote:
>>>> A macro can do this:
>>>>
>>>> a = BIT(b,10,1);
>>>>
>>>> and works everywhere. What you need is a typeof extension to make it
>>>> work with different integer types while retaining efficiency, otherwise
>>>> you're looking at making it assume 64 bit, or saddling it with a type
>>>> name argument.
>>>
>>> One should not have to write macros for commonly used language elements.
>>
>> Your extension is not commonly used, because it only exists in your
>> tool.  People who need to do a lot of bit slicing and don't like masking
>> and shifting (or struct bit-fields) should not have trouble defining:
>>
>> #define BIT(x, top, bottom) \
>>     (((x) >> (bottom)) & ((1llu << ((top) - (bottom) + 1)) - 1))
>>
>> Yes, the parenthesis you need for macros are ugly, but you only need to
>> get it right once, and now you can read your bit-fields.
>>
>> Having said that, it is not at all unreasonable for an embedded compiler
>> to ship with extra headers, which would be an excellent place to put
>> macros like this for user convenience.  It would be simpler and clearer
>> to C programmers who are not used to your extensions.  This is the
>> technique used by other embedded compilers.
>>
>> I'm not saying the extension is not useful, or bad in itself - but I
>> dislike adding extensions when it is perfectly possible to get the same
>> results without changing the language.
>
> Then there would have been no need for the [] indexing syntax either.
> You'd just write:
>
>   GETINDEX(a, i)
>   SETINDEX(a, i, x)
>
> instead of a[i] or a[i]=x. Except these need special headers to be
> dragged in, and everyone would be using their own incompatible macros;
> try mixing code from different sources.

In a programming language, you want convenient syntax for things you do
a lot, and you can happily have inconvenient syntax for things you only
need to do occasionally. (This works the other way too - you pick a
language that has convenient syntax for the things you do often. Or at
least, that's what sensible programmers do. Some people prefer to pick
a language they don't like and complain instead.)

Accessing bit-fields like this is very rare - even in embedded
programming, it is not something you do so much that existing C syntax
is a problem. Accessing arrays, however, is massively useful.

>
>> You need very good reasons for
>> adding non-portable extensions.
>
> Such a set of macros as you propose would also be non-portable unless
> you included custom headers. And then you mix code that needs
> BIT(a,10,1) with code that needs BIT(a,1,10).

Yes, but the great thing about headers with simple macros is that they
are extremely portable.

>
> You don't however seem to mind using GNU C extensions!

No, I don't - but I generally don't need my code to be portable beyond
gcc and occasionally a few older embedded compilers.

There are two C and C++ toolchains that totally dominate - MSVC on
Windows, and gcc on everything else. The next most popular toolchains
are clang then probably icc, both of which support a fair number of gcc
extensions.

So a gcc extension is likely to be portable to perhaps 90% of all
non-Windows C or C++ development work. That's more than good enough for
my needs.

An extension in /your/ tool, or Robert Finch's tool, is portable to
perhaps 0.0000000001% of C or C++ development work. That is rather
different.

Of course if you are writing code that only ever needs to run on these
home-made tools, then use your extensions - you made them, so use them.

Re: naked switches

<scc2cs$orb$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17403&group=comp.lang.c#17403

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 13:04:40 +0100
Organization: A noiseless patient Spider
Lines: 81
Message-ID: <scc2cs$orb$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <sc9gav$iln$1@dont-email.me>
<scc085$6h2$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 10 Jul 2021 12:04:44 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="25451"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX196/SmrO5mP5pXrl0ikTXGBnn+Gcn9Y3Sc="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:FGGtz/5b29gtFQTvlhngbg57Vvs=
In-Reply-To: <scc085$6h2$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210709-8, 9/7/2021), Outbound message
 by: Bart - Sat, 10 Jul 2021 12:04 UTC

On 10/07/2021 12:28, David Brown wrote:
> On 09/07/2021 14:44, Bart wrote:

>> Then there would have been no need for the [] indexing syntax either.
>> You'd just write:
>>
>>   GETINDEX(a, i)
>>   SETINDEX(a, i, x)
>>
>> instead of a[i] or a[i]=x. Except these need special headers to be
>> dragged in, and everyone would be using their own incompatible macros;
>> try mixing code from different sources.
>
> In a programming language, you want convenient syntax for things you do
> a lot, and you can happily have inconvenient syntax for things you only
> need to do occasionally. (This works the other way too - you pick a
> language that has convenient syntax for the things you do often. Or at
> least, that's what sensible programmers do. Some people prefer to pick
> a language they don't like and complain instead.)
>
> Accessing bit-fields like this is very rare - even in embedded
> programming, it is not something you do so much that existing C syntax
> is a problem. Accessing arrays, however, is massively useful.

It's probably rare because the language doesn't support them! If
available, they would be used a lot more. (As you've said, the macro to
set the value of an arbitrary bitfield is not trivial.)

C does have bitfield indexing, but only for named fields in structs and
with poor control over layout. Having it available for any integer value
would be convenient.

I don't use bit/bitfield indexing that much, but the underlying
mechanisms needed for that are used to implement my own,
better-controlled version of C's struct bitfields.

And used to allow things like A.msb (as both lvalue and rvalue), and
A.even/A.odd (rvalue only).

>
>>
>>> You need very good reasons for
>>> adding non-portable extensions.
>>
>> Such a set of macros as you propose would also be non-portable unless
>> you included custom headers. And then you mix code that needs
>> BIT(a,10,1) with code that needs BIT(a,1,10).
>
> Yes, but the great thing about headers with simple macros is that they
> are extremely portable.

Nothing is more portable than what is built-in to a language or to a
standard library.

I keep coming across macros for min and max, or MIN and MAX, or ones to
extract an array length without having to do that dance with sizeof this
over sizeof that. All candidates for standardisation.

>>
>> You don't however seem to mind using GNU C extensions!
>
> No, I don't - but I generally don't need my code to be portable beyond
> gcc and occasionally a few older embedded compilers.
>
> There are two C and C++ toolchains that totally dominate - MSVC on
> Windows, and gcc on everything else. The next most popular toolchains
> are clang then probably icc, both of which support a fair number of gcc
> extensions.
>
> So a gcc extension is likely to be portable to perhaps 90% of all
> non-Windows C or C++ development work. That's more than good enough for
> my needs.
>
> An extension in /your/ tool, or Robert Finch's tool, is portable to
> perhaps 0.0000000001% of C or C++ development work. That is rather
> different.

The ideas would be portable to 99% of C implementations if they prove
viable and useful (remember my 'strinclude' feature). Where do you think
most gcc extensions came from?

Re: naked switches

<scc7tq$cr9$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17406&group=comp.lang.c#17406

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 15:39:05 +0200
Organization: A noiseless patient Spider
Lines: 109
Message-ID: <scc7tq$cr9$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <sc9gav$iln$1@dont-email.me>
<scc085$6h2$1@dont-email.me> <scc2cs$orb$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 10 Jul 2021 13:39:06 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="199b2681e3d790bf87f77b24379e3e4a";
logging-data="13161"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/wviuohFNmnjUmsdJYNwH//Ocpgx3Sa0s="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:IysZA6KXgSegcoL8b4Bes/Vjlw8=
In-Reply-To: <scc2cs$orb$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Sat, 10 Jul 2021 13:39 UTC

On 10/07/2021 14:04, Bart wrote:
> On 10/07/2021 12:28, David Brown wrote:
>> On 09/07/2021 14:44, Bart wrote:
>
>>> Then there would have been no need for the [] indexing syntax either.
>>> You'd just write:
>>>
>>>    GETINDEX(a, i)
>>>    SETINDEX(a, i, x)
>>>
>>> instead of a[i] or a[i]=x. Except these need special headers to be
>>> dragged in, and everyone would be using their own incompatible macros;
>>> try mixing code from different sources.
>>
>> In a programming language, you want convenient syntax for things you do
>> a lot, and you can happily have inconvenient syntax for things you only
>> need to do occasionally.  (This works the other way too - you pick a
>> language that has convenient syntax for the things you do often.  Or at
>> least, that's what sensible programmers do.  Some people prefer to pick
>> a language they don't like and complain instead.)
>>
>> Accessing bit-fields like this is very rare - even in embedded
>> programming, it is not something you do so much that existing C syntax
>> is a problem.  Accessing arrays, however, is massively useful.
>
>
> It's probably rare because the language doesn't support them!

No, it is because bit-fields like this are not commonly useful.

> If
> available, they would be used a lot more. (As you've said, the macro to
> set the value of an arbitrary bitfield is not trivial.)
>
> C does have bitfield indexing, but only for named fields in structs and
> with poor control over layout. Having it available for any integer value
> would be convenient.

I really don't see that. And I do the kind of work where it would be
most likely to be useful.

(I would have liked clearer specifications of bit-field layout in C.)

>
> I don't use bit/bitfield indexing that much, but the underlying
> mechanisms needed for that are used to implement my own,
> better-controlled version of C's struct bitfields.
>
> And used to allow things like A.msb (as both lvalue and rvalue), and
> A.even/A.odd (rvalue only).
>

Why? Can you give examples where these would be used often enough to
deserve their own special syntax, and where that syntax would be clearer
than "x & 1", "x |= 1", "x % 2", etc.?

(I'll accept that masking off a bit - "x &= ~1u" - is not great.)

>>
>>>
>>>> You need very good reasons for
>>>> adding non-portable extensions.
>>>
>>> Such a set of macros as you propose would also be non-portable unless
>>> you included custom headers. And then you mix code that needs
>>> BIT(a,10,1) with code that needs BIT(a,1,10).
>>
>> Yes, but the great thing about headers with simple macros is that they
>> are extremely portable.
>
> Nothing is more portable than what is built-in to a language or to a
> standard library.
>
> I keep coming across macros for min and max, or MIN and MAX, or ones to
> extract an array length without having to do that dance with sizeof this
> over sizeof that. All candidates for standardisation.
>

These could certainly be standardised in some way, I agree. C++ has
done so.

>>>
>>> You don't however seem to mind using GNU C extensions!
>>
>> No, I don't - but I generally don't need my code to be portable beyond
>> gcc and occasionally a few older embedded compilers.
>>
>> There are two C and C++ toolchains that totally dominate - MSVC on
>> Windows, and gcc on everything else.  The next most popular toolchains
>> are clang then probably icc, both of which support a fair number of gcc
>> extensions.
>>
>> So a gcc extension is likely to be portable to perhaps 90% of all
>> non-Windows C or C++ development work.  That's more than good enough for
>> my needs.
>>
>> An extension in /your/ tool, or Robert Finch's tool, is portable to
>> perhaps 0.0000000001% of C or C++ development work.  That is rather
>> different.
>
> The ideas would be portable to 99% of C implementations if they prove
> viable and useful (remember my 'strinclude' feature). Where do you think
> most gcc extensions came from?

It's absolutely fine to try out new ideas for extensions in a compiler,
and if they look good, suggest to other compilers that it would be a
useful extension there. If some idea really is useful, it's quite
likely that many people will think of basically the same think and
there's a chance it will get into the language sooner or later.

Re: naked switches

<scc9k8$rth$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17407&group=comp.lang.c#17407

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 15:08:05 +0100
Organization: A noiseless patient Spider
Lines: 59
Message-ID: <scc9k8$rth$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <sc9gav$iln$1@dont-email.me>
<scc085$6h2$1@dont-email.me> <scc2cs$orb$1@dont-email.me>
<scc7tq$cr9$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 14:08:08 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="28593"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+9vIRh0xVcfGad+qwkh25VMZqAug5JJLY="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:PIcnqLgKb3aPntUjcXfdnv4qVDk=
In-Reply-To: <scc7tq$cr9$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210710-2, 10/7/2021), Outbound message
 by: Bart - Sat, 10 Jul 2021 14:08 UTC

On 10/07/2021 14:39, David Brown wrote:
> On 10/07/2021 14:04, Bart wrote:

>> It's probably rare because the language doesn't support them!
>
> No, it is because bit-fields like this are not commonly useful.
>
>> If
>> available, they would be used a lot more. (As you've said, the macro to
>> set the value of an arbitrary bitfield is not trivial.)
>>
>> C does have bitfield indexing, but only for named fields in structs and
>> with poor control over layout. Having it available for any integer value
>> would be convenient.
>
> I really don't see that. And I do the kind of work where it would be
> most likely to be useful.

Maybe you're too used with dealing with bit manipulation using code like
your examples below.

I guess you don't use macros like GETBIT, as that would mean you do find
it useful.

>> And used to allow things like A.msb (as both lvalue and rvalue), and
>> A.even/A.odd (rvalue only).
>>
>
> Why? Can you give examples where these would be used often enough to
> deserve their own special syntax, and where that syntax would be clearer
> than "x & 1", "x |= 1", "x % 2", etc.?
>
> (I'll accept that masking off a bit - "x &= ~1u" - is not great.)

OK, I'll try to translate your examples (into my syntax not CC64 if
that's the OP's compiler):

x & 1 x.[0] (or x.lsbit) extract least sig bit

x |= 1 x.[0] := 1 Set ls bit to 1

x % 2 x.[0] (When x is positive or unsigned)

x &= ~1u x.[0] := 0 Set ls bit to 0

I had to think carefully about these, then double check.

Even if correct, these may not directly reflect your intentions. Whereas
those bit operations are exactly that.

Somebody looking at x & k would not be able to tell if k refered to a
single bit, a contiguous bit, or is some arbitrary value that cannot be
expressed as a bit-index op. (Not without making it more elaborate.)

Somebody looking at x.[k] could.

Dedicated ops just make this stuff incredibly easy, with less chance of
error. Notice that in C, all those bit-0 manipulations used either 1 or 2

Re: naked switches

<sccelb$u6s$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17415&group=comp.lang.c#17415

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 17:34:03 +0200
Organization: A noiseless patient Spider
Lines: 90
Message-ID: <sccelb$u6s$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <sc9gav$iln$1@dont-email.me>
<scc085$6h2$1@dont-email.me> <scc2cs$orb$1@dont-email.me>
<scc7tq$cr9$1@dont-email.me> <scc9k8$rth$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 10 Jul 2021 15:34:03 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="199b2681e3d790bf87f77b24379e3e4a";
logging-data="30940"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+Xg88ns9THEpnI7ufryu60YiBVoHFMMWU="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Thunderbird/68.10.0
Cancel-Lock: sha1:CXUe4UEixbGHXchZliBQazV45fU=
In-Reply-To: <scc9k8$rth$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Sat, 10 Jul 2021 15:34 UTC

On 10/07/2021 16:08, Bart wrote:
> On 10/07/2021 14:39, David Brown wrote:
>> On 10/07/2021 14:04, Bart wrote:
>
>>> It's probably rare because the language doesn't support them!
>>
>> No, it is because bit-fields like this are not commonly useful.
>>
>>> If
>>> available, they would be used a lot more. (As you've said, the macro to
>>> set the value of an arbitrary bitfield is not trivial.)
>>>
>>> C does have bitfield indexing, but only for named fields in structs and
>>> with poor control over layout. Having it available for any integer value
>>> would be convenient.
>>
>> I really don't see that.  And I do the kind of work where it would be
>> most likely to be useful.
>
> Maybe you're too used with dealing with bit manipulation using code like
> your examples below.
>
> I guess you don't use macros like GETBIT, as that would mean you do find
> it useful.

I don't use macros like GETBIT, no. Most often, I use the method
defined by the microcontroller manufacturer that provided the header
file for accessing the hardware registers for the microcontroller.
Sometimes that is bit-field structs, but most often it is with
structures, constants and macros so that you write something on the
lines of :

timer1.controlreg |= TIMER_CONTROLREG_CLOCKSOURCE(4);

for setting the "clocksource" field of timer 1's control register to 4.

And if it is something I am using more than once or twice, it is going
to be wrapped in a function anyway.

A compiler extension to let me access bits of a variable via array-like
syntax would be of precisely /zero/ use to me here.

>
>>> And used to allow things like A.msb (as both lvalue and rvalue), and
>>> A.even/A.odd (rvalue only).
>>>
>>
>> Why?  Can you give examples where these would be used often enough to
>> deserve their own special syntax, and where that syntax would be clearer
>> than "x & 1", "x |= 1", "x % 2", etc.?
>>
>> (I'll accept that masking off a bit - "x &= ~1u" - is not great.)
>
> OK, I'll try to translate your examples (into my syntax not CC64 if
> that's the OP's compiler):
>
>   x & 1          x.[0]        (or x.lsbit) extract least sig bit
>
>   x |= 1         x.[0] := 1   Set ls bit to 1
>
>   x % 2          x.[0]        (When x is positive or unsigned)
>
>   x &= ~1u       x.[0] := 0   Set ls bit to 0
>
> I had to think carefully about these, then double check.
>

Your syntax is clear enough - why would you have to think hard about it?
Or are you just saying you are not very familiar with C?

(I don't think there is anything bad about your syntax, I just don't see
it as a particularly useful feature or one worth adding to C.)

> Even if correct, these may not directly reflect your intentions. Whereas
> those bit operations are exactly that.
>
> Somebody looking at x & k would not be able to tell if k refered to a
> single bit, a contiguous bit, or is some arbitrary value that cannot be
> expressed as a bit-index op. (Not without making it more elaborate.)
>
> Somebody looking at x.[k] could.
>
> Dedicated ops just make this stuff incredibly easy, with less chance of
> error. Notice that in C, all those bit-0 manipulations used either 1 or 2
>

They are easy enough in C. And since they are rarely needed in practice
(you haven't given examples of real-world use-cases), "easy enough" is
all you need. "Incredibly easy" doesn't add much - you would be better
off spending the effort elsewhere.

Re: naked switches

<sccivt$s3k$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17421&group=comp.lang.c#17421

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: naked switches
Date: Sat, 10 Jul 2021 17:47:53 +0100
Organization: A noiseless patient Spider
Lines: 89
Message-ID: <sccivt$s3k$1@dont-email.me>
References: <06a0049a-2d7d-40f0-899a-fb35c9a15d5fn@googlegroups.com>
<8735sp8cbm.fsf@nosuchdomain.example.com>
<255c09e7-2365-4983-ad4d-3bfc83cf04e7n@googlegroups.com>
<31342574-cb69-4ad6-8576-387dcf9caf70n@googlegroups.com>
<sc76v8$8ah$1@dont-email.me>
<7e094b82-01be-4d7f-9793-4eeda725ca0en@googlegroups.com>
<20210708103653.702@kylheku.com>
<9a999021-6733-4d00-91fb-9797570a1328n@googlegroups.com>
<sc9190$h4g$1@dont-email.me> <sc9gav$iln$1@dont-email.me>
<scc085$6h2$1@dont-email.me> <scc2cs$orb$1@dont-email.me>
<scc7tq$cr9$1@dont-email.me> <scc9k8$rth$1@dont-email.me>
<sccelb$u6s$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 16:47:57 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="28788"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/HRjmo7DvNwC7rB7KRcjphK8eSGhpEJlA="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:yX4jWpLaq2otzYS662DiZWYwPUU=
In-Reply-To: <sccelb$u6s$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210710-2, 10/7/2021), Outbound message
 by: Bart - Sat, 10 Jul 2021 16:47 UTC

On 10/07/2021 16:34, David Brown wrote:
> On 10/07/2021 16:08, Bart wrote:

>> I guess you don't use macros like GETBIT, as that would mean you do find
>> it useful.
>
> I don't use macros like GETBIT, no. Most often, I use the method
> defined by the microcontroller manufacturer that provided the header
> file for accessing the hardware registers for the microcontroller.
> Sometimes that is bit-field structs, but most often it is with
> structures, constants and macros so that you write something on the
> lines of :
>
> timer1.controlreg |= TIMER_CONTROLREG_CLOCKSOURCE(4);
>
> for setting the "clocksource" field of timer 1's control register to 4.
>
> And if it is something I am using more than once or twice, it is going
> to be wrapped in a function anyway.
>
> A compiler extension to let me access bits of a variable via array-like
> syntax would be of precisely /zero/ use to me here.

It would be of use to the manufacturer who provides the header file.

But I'm not sure your example is correct; if clocksource is a bitfield
of timer.controlreg, it would only set it to 4 if it's currently zero
(or already 4).

What does TIMER_CONTROLREG_CLOCKSOURCE do, shift the 4 up to be in the
right place, making sure other bits are zero? To /replace/ the field is
a more complex operation.

If clocksource is a 4-bit field, say occupying bits 8..11, bitfield ops
would allow:

timer.controlreg.[8..11] := 4
timer.controlreg[11:8] = 4 // with CC64

Although you would define constants or macros for these so that you'd
write .clocksource or .[clocksource].

>> I had to think carefully about these, then double check.
>>
>
> Your syntax is clear enough - why would you have to think hard about it?
> Or are you just saying you are not very familiar with C?

I had to decode the C to see exactly what you were attempting

>> Dedicated ops just make this stuff incredibly easy, with less chance of
>> error. Notice that in C, all those bit-0 manipulations used either 1 or 2
>>
>
> They are easy enough in C. And since they are rarely needed in practice
> (you haven't given examples of real-world use-cases), "easy enough" is
> all you need. "Incredibly easy" doesn't add much - you would be better
> off spending the effort elsewhere.

Every real-world example could be done with logical operations or using
a different approach entirely; it's always very easy in a 1-line example
on a forum where people can find these solutions at leisure.

(For that matter, all logical operations could probably be replaced by
arihtmetic ones too.)

It's about not spending a few seconds having to stop think about this
when writing or reading, which is a distraction from what you really
want to do, which is to get or set some bits without worrying about the
mechanisms for doing so, or having to instruct the compiler how to.

But there's one example which was a debug print of an int that
represented a colour value:

println "rgb=",col.[0..7],col.[8..15],col.[16..23]

Another from some old code, which here defines bits or bitfields which
are accessed using A.[fnfont] and so on:

macro fnfont = 0..5
macro fnsize = 6..12
macro fnbold = 13
macro fnitalic = 14
macro fnunderline = 15
macro fnattrib = fnbold..fnunderline
macro fnaspect = 16..18
macro fncolour = 19..24
macro fnbgnd = 25..30

Pages:123
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor