Deutsch   English   Français   Italiano  
<vjm94b$gr56$2@dont-email.me>

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

Path: ...!news.misty.com!weretis.net!feeder9.news.weretis.net!news.quux.org!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: C89 "bug"
Date: Sun, 15 Dec 2024 10:56:27 +0100
Organization: A noiseless patient Spider
Lines: 84
Message-ID: <vjm94b$gr56$2@dont-email.me>
References: <vjh8hu$3den0$1@dont-email.me>
 <87jzc3v48r.fsf@nosuchdomain.example.com> <vjhu52$3i4tq$1@dont-email.me>
 <vjhvnv$3igdc$1@dont-email.me> <vjii1o$3lr2l$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 15 Dec 2024 10:56:27 +0100 (CET)
Injection-Info: dont-email.me; posting-host="3bc4e255890a8c3d497605071ae0a7d9";
	logging-data="552102"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/Md+f1SmWzC+ymNc3SR9pulmbaiJXnv7A="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:rDw18Bf/gUuFPvaI4mseRURqeno=
Content-Language: en-GB
In-Reply-To: <vjii1o$3lr2l$1@dont-email.me>
Bytes: 3995

On 14/12/2024 01:04, bart wrote:
> On 13/12/2024 18:51, David Brown wrote:
>> On 13/12/2024 19:24, Thiago Adams wrote:
>>> Em 12/13/2024 3:15 PM, Keith Thompson escreveu:
>>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>>>> Does anyone knows how can I convert this code (external 
>>>>> declaration) to C89?
>>>>>
>>>>> union U {
>>>>>      int i;
>>>>>      double d;
>>>>> };
>>>>>
>>>>> union U  u = {.d=1.2};
>>>>>
>>>>> The problem is that in C89 only the first member of the union is
>>>>> initialized.
>>>>
>>>> The obvious solution is:
>>>>      union U u;
>>>>      u.d = 1.2;
>>>> But that works only if u has automatic storage duration.
>>>>
>>>> You could also define a function that takes a double argument and
>>>> returns a union U result.
>>>
>>> Like this?
>>> union U {
>>>      int i;
>>>      double d;
>>> };
>>> union U f(){ union U u; u.d = 1.2; return u;}
>>> union U u = f();
>>>
>>> The problem is that f() is not a constant expression for external 
>>> declarations.
>>>
>>
>> Can you use gcc extensions here, or are you looking for strict C89 
>> compliance?
>>
>> (To me, the "bug" is using C89 in the first place, but you have your 
>> reasons for that.)
>>
>> Another option if you are generating code is to make your union :
>>
>> union U {
>>      struct { unsigned int lo; unsigned int hi; } raw;
>>      int i;
>>      double d;
>> };
>>
>> and always initialise it with the underlying representation for the 
>> values and types that you want.  (I believe you are generating the 
>> code, so that should be practical even for floating point data.)
>>
>> However, that puts a dependency on the endianness and size of types.
>>
> 
> It gets a bit tricky also if it includes initialised 64-bit pointers 
> (you can't split those). And also if the fields are deliberately 
> misaligned (so using an intptr_t array won't be enough).
> 

Those are good points.  Perhaps one size does not fit all here, and the 
OP might want "raw" to be an appropriately sized "unsigned char" array 
for most cases, and a "void *" pointer to handle pointers.  However, I 
can't think of any standard C89 way to handle the situation where you 
have a platform with pointers bigger than "unsigned long", if he needs 
to target such systems.

AFAIUI he is dealing only with standard C - thus there is no way to make 
unaligned fields, so that problem can be ignored!


> There are other issues as well, but this depends on how far the OP is 
> going. For example, when the definition for the union is inside an 
> imported third party header, so only the initialisation is inside the 
> code being translated.
> 
> But maybe those external types will be recreated so can be augmented.