Deutsch   English   Français   Italiano  
<v4mg7i$tfe$1@dont-email.me>

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

Path: ...!feed.opticnetworks.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: Re: "undefined behavior"?
Date: Sun, 16 Jun 2024 12:53:38 +0200
Organization: A noiseless patient Spider
Lines: 46
Message-ID: <v4mg7i$tfe$1@dont-email.me>
References: <666a095a$0$952$882e4bbb@reader.netnews.com>
 <8t3k6j5ikf5mvimvksv2t91gbt11ljdfgb@4ax.com>
 <666a18de$0$958$882e4bbb@reader.netnews.com>
 <87y1796bfn.fsf@nosuchdomain.example.com>
 <666a2a30$0$952$882e4bbb@reader.netnews.com>
 <87tthx65qu.fsf@nosuchdomain.example.com> <v4dtlt$23m6i$1@dont-email.me>
 <NoEaO.2646$J8n7.2264@fx12.iad> <v4fc5j$2cksu$1@dont-email.me>
 <v4ff97$2d8l1$1@dont-email.me> <87o784xusf.fsf@bsb.me.uk>
 <v4g7i3$2icc2$1@dont-email.me> <87ikybycj6.fsf@bsb.me.uk>
 <v4hk5v$2tttf$1@dont-email.me> <87cyojxlgj.fsf@bsb.me.uk>
 <v4igj8$330vf$2@dont-email.me> <v4ko7d$3jbip$1@dont-email.me>
 <v4kput$3joiu$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 16 Jun 2024 12:53:38 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="efa9642fc1579e8fdfcdda80d78f3954";
	logging-data="30190"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+EcYTbEsT8JzTjCSqkmLGqJ4R7LUBAnWY="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:a1T1LBvvEga48Bt2mmeudlTRxyY=
Content-Language: en-GB
In-Reply-To: <v4kput$3joiu$1@dont-email.me>
Bytes: 3634

On 15/06/2024 21:27, Richard Harnden wrote:
> On 15/06/2024 19:57, David Brown wrote:
>>
>> If you want BBX_RGBA to be a typedef for an unsigned 32-bit integer, 
>> write:
>>
>>      typedef uint32_t BBX_RGBA;
>>
>> If you want bbx_rgba() to be a function that is typesafe, correct, and 
>> efficient (for any decent compiler), write :
>>
>>      static inline BBX_RGBA bbx_rgba(uint32_t r, uint32_t g,
>>              uint32_t b, uint32_t a)
>>      {
>>          return (r << 24) | (g << 16) | (b << 8) | a;
>>      }
>>
> 
> Shouldn't that be ... ?
> 
> static inline BBX_RGBA bbx_rgba(uint8_t r, uint8_t g,
>          uint8_t b, uint8_t a)
> 

As Ben says, that will not work on its own - "r" would get promoted to 
signed int before the shift, and we are back to undefined behaviour.

I think there is plenty of scope for improvement in a variety of ways, 
depending on what the author is looking for.  For example, uint8_t might 
not exist on all platforms (indeed there are current processors that 
don't support it, not just dinosaur devices).  But any system that 
supports a general-purpose gui, such as Windows or *nix systems, will 
have these types and will also have a 32-bit int.  So the code author 
can balance portability with convenient assumptions.

There are also balances to be found between run-time checking and 
efficiency, and how to handle bad data.  If the function can assume that 
no one calls it with values outside 0..255, or that it doesn't matter 
what happens if such values are used, then you don't need any checks. 
As it stands, with uint32_t parameters, out-of-range values will lead to 
fully defined but wrong results.  Switching to "uint8_t" types would 
give a different fully defined but wrong result.  Maybe the function 
should use saturation, or run-time checks and error messages - that will 
depend on where it is in the API, what the code author wants, and what 
users expect.