Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 43 |
Nodes: | 6 (0 / 6) |
Uptime: | 94:25:37 |
Calls: | 290 |
Calls today: | 1 |
Files: | 904 |
Messages: | 76,378 |
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.
unfortunately, this solution does not work if we have two objects.
union U {
double d;
int i;
};
union U u1 = { .d=2.2 };
union U u2 = { .i=1 };
Em 12/13/2024 12:01 PM, Kaz Kylheku escreveu:
On 2024-12-13, Thiago Adams <thiago.adams@gmail.com> wrote:
unfortunately, this solution does not work if we have two objects.
union U {
double d;
int i;
};
union U u1 = { .d=2.2 };
union U u2 = { .i=1 };
Idea: have several declarations of the union in different translation
units.
/* translation unit for u1 */
union U {
double d;
int i;
};
extern union U u1 = { 2.2 };
/* translation unit for u2 */
union U {
int i;
double d;
};
extern union U u2 = { 1 };
another solution could be call a function that initializes before main.
extern union U u1;
void before_main()
{
u1.d = 1.2;
}
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.
Thiago Adams <thiago.adams@gmail.com> writes:
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)The obvious solution is:
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.
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.
Yes, that's a good point. Even in modern C, the initializer for
a static object has to be constant.
A function probably doesn't have much advantage over assigning
the member directly. Either way, that code has to be executed in
some function.
If this is in human-written code, then there's the risk of forgetting
to invoke the initialization code (or invoking it at the wrong time),
since it can't be directly associated with the object definition.
That's why the C99 and later solution is IMHO much better.)
But if this is generated code, you can just generate code to do
the assignment, perhaps in main().
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.
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.
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).
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.