Deutsch   English   Français   Italiano  
<v4ko7d$3jbip$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: Sat, 15 Jun 2024 20:57:49 +0200
Organization: A noiseless patient Spider
Lines: 152
Message-ID: <v4ko7d$3jbip$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>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 15 Jun 2024 20:57:49 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f678a482ffafce70c2ceef8ecfac3e10";
	logging-data="3780185"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+yf1HSZAZI11A7LvpZEnTobkEomUCfth8="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:h9aiDvprzt++/2yw3+7KhjDWUw4=
In-Reply-To: <v4igj8$330vf$2@dont-email.me>
Content-Language: en-GB
Bytes: 7433

On 15/06/2024 00:35, Malcolm McLean wrote:
> On 14/06/2024 22:29, Ben Bacarisse wrote:
>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>>
>>> On 14/06/2024 12:44, Ben Bacarisse wrote:
>>>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>>>>
>>>>> On 14/06/2024 00:55, Ben Bacarisse wrote:
>>>>>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>>>>>>
>>>>>>> On 13/06/2024 19:01, bart wrote:
>>>>>>
>>>>>>>> And here it just gets even uglier. You also get situations like 
>>>>>>>> this:
>>>>>>>>         uint64_t i=0;
>>>>>>>>         printf("%lld\n", i);
>>>>>>>> This compiles OK with gcc -Wall, on Windows64. But compile under 
>>>>>>>> Linux64
>>>>>>>> and it complains the format should be %ld. Change it to %ld, and it
>>>>>>>> complains under Windows.
>>>>>>>> It can't tell you that you should be using one of those 
>>>>>>>> ludicrous macros.
>>>>>>>> I've also just noticed that 'i' is unsigned but the format calls 
>>>>>>>> for
>>>>>>>> signed. That may or may not be deliberate, but the compiler 
>>>>>>>> didn't say
>>>>>>>> anything.
>>>>>>>>
>>>>>>> Exactly. We can't have this just to print out an integer.
>>>>>> This is how C works.  There's no point in moaning about it.  Use 
>>>>>> another
>>>>>> language or do what you have to in C.
>>>>>>
>>>>>>> In Baby X I provide a function called bbx_malloc(). It's is 
>>>>>>> guaranteed
>>>>>>> never to return null. Currently it just calls exit() on 
>>>>>>> allocation failure.
>>>>>>> But it also limits allocation to slightly under INT_MAX. Which 
>>>>>>> should be
>>>>>>> plenty for a Baby program, and if you want more, you always have 
>>>>>>> big boy's
>>>>>>> malloc.
>>>>>> And if you need to change the size?
>>>>>>
>>>>>>> But at a stroke, that gets rid of any need for size_t,
>>>>>> But sizeof, strlen (and friends like the mbs... and wcs... 
>>>>>> functions),
>>>>>> strspn (and friend), strftime, fread, fwrite. etc. etc. all return
>>>>>> size_t.
>>>>>>
>>>>> But these are not Baby X functions.
>>>> Neither is malloc but you wanted t replace that to get rid of the need
>>>> for size_t.
>>>> I confess that I am all at sea about what you are doing.  In essence, I
>>>> don't understand the rules of the game so I should probably just stop
>>>> commenting.
>>>>
>>> Yes, I really need to get that website together so that people cotton 
>>> on to
>>> what Baby X is, what it can and cannot do, and what is the point.
>>
>> I know what Baby X is.  I don't know why "these are not Baby X
>> functions" applies to the ones I listed and not to malloc.
>>
>> ...
>>> However if you need to pass a colour value to a fuction, you normall 
>>> pass a
>>> BBX_RGBA value, which is typedefed to unsigned long, and is opaque, 
>>> and you
>>> query the channels using the macros in bbx_color.h
>>>
>>> #ifndef bbx_color_h
>>> #define bbx_color_h
>>>
>>> typedef unsigned long BBX_RGBA;
>>
>>
>> Curious.  The macros below seem to assume that int is 32 bits, so why
>> use long?
>>
>>> #define bbx_rgba(r,g,b,a) ((BBX_RGBA) ( ((r) << 24) | ((g) << 16) | 
>>> ((b) <<
>>> 8) | (a) ))
>>
>> This is likely to involve undefined behaviour when r >= 128.  (I presume
>> you are ruling out int narrower than 32 bits or there are other problems
>> as well.)
>>
> 
> No, it's been miswritten. Which is what I mean about C's integer types 
> being a source of bugs. That code does not look buggy, but it is.
> 
>>> #define bbx_rgb(r, g, b) bbx_rgba(r,g,b, 255)
>>> #define bbx_red(col) ((col >> 24) & 0xFF)
>>> #define bbx_green(col) ((col >> 16) & 0xFF)
>>> #define bbx_blue(col) ((col >> 8) & 0xFF)
>>> #define bbx_alpha(col) (col & 0xFF)
>>
>> It might not be an issue (as col is opaque and unlikely to be an
>> expression) but I'd still write (col) here to stop the reader having to
>> check or reason that out.
>>
>>> #define BBX_RgbaToX(col) ( (col >> 8) & 0xFFFFFF )
>>>
>>> #endif
>>>
>>> The last macro is to make it easier to interface with Xlib, and has the
>>> prefix BBX_ (upper case) indicating that it is for internal use by 
>>> the bbx
>>> library / system and not meant for user programs.
>>
>> As a reader of the code, I made exactly the reverse assumption.  When I
>> see lower-case macros I assume they are for internal use.
>>
> 
> 
> They're function-like macros. Iterating over an rgba buffer is very 
> processor-intensive, and so we do haave to compromise sfatety for speed 
> here. All function-like symbols bbx_ are provided by Baby X for users, 
> all symbols BBX_ have that prefix to reduce the chance of collisions 
> with other code.
> 

In this little exchange, there have been several points where your code 
is unclear, inefficient, non-portable or downright buggy, purely due to 
your insistence in using an outdated version of C.

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;
	}

If you want your colour types to be "opaque", as you claimed, make it a 
struct with inline accessor functions.

Use static inline functions instead of function-like macros and you 
don't need the extra parenthesis round things (and you don't need to 
justify to readers why they are not there).  You can use small letter 
names without running contrary to common conventions.

Your insistence on hobbling your choice of language shows through in the 
poor quality of the code - or at least, the missed opportunities to make 
the code better and safer for both you and your users.