Deutsch   English   Français   Italiano  
<vson4q$3htha$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!news.tomockey.net!news.samoylyk.net!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: Re: "A diagram of C23 basic types"
Date: Fri, 4 Apr 2025 15:34:18 +0200
Organization: A noiseless patient Spider
Lines: 121
Message-ID: <vson4q$3htha$1@dont-email.me>
References: <87y0wjaysg.fsf@gmail.com> <vsj1m8$1f8h2$1@dont-email.me>
 <vsj2l9$1j0as$1@dont-email.me> <vsjef3$1u4nk$1@dont-email.me>
 <vsjg6t$20pdb$1@dont-email.me> <vsjjd1$23ukt$1@dont-email.me>
 <vsjkvb$25mtg$1@dont-email.me> <vpdHP.1828825$TBhc.94105@fx16.iad>
 <vslhrm$7uv3$1@dont-email.me> <vsll4b$8mfb$3@dont-email.me>
 <vslq6b$ginf$1@dont-email.me> <vsnh11$28q4m$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 04 Apr 2025 15:34:19 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="c769e35c057c19c3049ecfc31d4accc3";
	logging-data="3733034"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18rLKpnNHF4yY9KtLveHd0pJ2ohKdkLeFI="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
 Thunderbird/102.11.0
Cancel-Lock: sha1:aVDGudojxY8CzTN8DAUFSrnRkE8=
Content-Language: en-GB
In-Reply-To: <vsnh11$28q4m$1@dont-email.me>
Bytes: 6734

On 04/04/2025 04:43, Janis Papanagnou wrote:
> On 03.04.2025 13:07, Muttley@DastardlyHQ.org wrote:
>> On Thu, 3 Apr 2025 11:41:31 +0200
>> David Brown <david.brown@hesbynett.no> wibbled:
> 
> [ "unreachable()" is now standard. ]
> 
>>> I can't tell you what Scott uses it for, but I have used gcc's
>>> __builtin_unreachable() a fair number of times in my coding.  I use it
>>> to inform both the compiler and human readers that a path is unreachable:
>>
>> What for? The compiler doesn't care and a human reader would probably
>> prefer a meaningful comment if its not obvious. If you're worried about the
>> code accidently going there use an assert.
>>
>>> 	switch (x) {
>>> 		case 1 : ...
>>> 		case 2 : ...
>>> 		case 3 : ...
>>> 		default : __builtin_unreachable();
>>> 	}
>>>
>>> I can also use it to inform the compiler about data :
>>>
>>> 	if ((x < 0) || (x > 10)) __builtin_unreachable();
>>> 	// x must be 1 .. 10
>>
>> And that'll do what? You want the compiler to compile in a hidden value check?
> 
> I also don't see a point here; myself I'd write some sort of assertion
> in such cases, depending on the application case either just temporary
> for tests or a static one with sensible handling of the case.
> 

It can't be a static assertion, since "x" is unknown at compile time. 
Dynamic assertions cost - runtime and code space.  That's fine during 
testing and debugging, or for non-critical code.  But for important code 
when you know a particular fact will hold true but the compile can't 
figure it out for itself, you don't want to pay that cost.  You also 
don't want to have run-time code that is untestable - such as for 
handling a situation that can never occur.

Usually I wrap my unreachable's in a macro that supports other static 
testing and optional run-time testing.  But ultimately it often results 
in more efficient final code.


>>
>>> Good use of __builtin_unreachable() can result in smaller and faster
>>> code, and possibly improved static error checking.  It is related to the
>>
>> Sorry, don't see how. If you think a piece of code is unreachable then don't
>> put it in in the first place!
> 
> Let me give that another spin...
> 
> In cases like above 'switch' code I have the habit to (often) provide
> a default branch that contains a fprintf(stderr, "Internal error: ..."
> or a similar logging command and some form of exit or trap/catch code.
> I want some safety for the cases where in the _evolving_ program bugs
> sneak in by an oversight.[*]

I might enable extra checks during testing and debugging.

But if the unreachable() is ever reached, the bug is not in that code - 
it is in the code that calls it.  A message from that code could 
conceivably help locate the bugging calling code, in conjunction with a 
debugger and a call trace.  But I don't want correct code to be weighed 
down by vague attempts at helping to find flaws in other code - if that 
were an acceptable way to write the code, I would not be using C in the 
first place!

> 
> Personally I don't care about a compiler who is clever enough to warn
> me, say, about a lacking default branch but not clever enough to notice
> that it's intentionally, cannot be reached (say, in context of enums).

enums in C are not guaranteed to be a value from the corresponding 
enumeration.  The compiler can't assume that "colour_to_hex" will not be 
called with a value of, say, 42, because the language says it is 
perfectly reasonable to do that.  (This is different from passing a 
"bool" parameter - the compiler /can/ assume that the parameter is 
either 0 or 1.)

> I can understand that it might be of use for others, though. (There's
> certainly some demand if it's now standard.)

My example was paraphrased from the C23 standard - that /is/ an 
appropriate and common use of it.

It has existed as a gcc extension for decades, and there is an 
equivalent in MSVC and many other serious compilers.  It was added to 
C++ (C++23, IIRC), along with an "assume" attribute that effectively 
combines a conditional and an unreachable().  Compilers implement 
"unreachable()" by treating it as undefined behaviour.

> 
> I'm uninformed about __builtin_unreachable(), I don't know whether it
> can be overloaded, user-defined, or anything. 

It is a gcc (and clang) extension - like all "__builtin" functions or 
pseudofunctions.  No, it cannot be overloaded or user defined.

> If that's not the case
> I'd anyway write my own "Internal error: unexpected ..." function to
> use that in all such cases for error detection and tracking of bugs.

Sure.  I typically have the call wrapped in a macro with extra features. 
  But those are a distraction in showing what unreachable() does and why 
it is useful.

> 
> Janis
> 
> [*] This habit is actually a very old one and most probably resulting
> from an early observation with one of my first Simula programs coded
> on a mainframe that told me: "Internal error! Please contact the NCC
> in Oslo." - BTW; a nice suggestion, but useless since back these days
> there was no Email available to me and the NCC was in another country.
>