Reputation: 7921
In a header outside of my control, there is this:
typedef union {
char * v_charp;
int v_int;
float v_float;
} value_t;
typedef struct var {
char *name;
value_t value;
} variable;
#define VARIABLE_DEF(Name, Value) {Name, {(char*)Value}}
They expect that in my code I'll do something like this:
variable my_variables[2] = {
VARIABLE_DEF("Variable 1", 1),
VARIABLE_DEF("Variable 2", 2)
};
Whoever wrote this apparently didn't consider that you might want to initialise the union with a floating-point literal. So I need to figure out how to convert a literal float to an integer of the same bit-pattern. If I could use an intermediate variable then it'd be easy:
float tmp;
variable my_variables[2] = {
VARIABLE_DEF("Variable 1", tmp = 1.1f, *((unsigned int *)(&tmp))),
VARIABLE_DEF("Variable 2", tmp = 2.2f, *((unsigned int *)(&tmp)))
};
But you can't use variables in struct initialisers. What else can I do?
Upvotes: 1
Views: 810
Reputation: 106117
Used named initializers:
variable my_variables[2] = {
VARIABLE_DEF("Variable 1", 1),
{ .name = "Variable 2", .value.v_float = 1.1f }
};
Upvotes: 0
Reputation: 4313
How about
variable my_variables[2] = {
VARIABLE_DEF("Variable 1", ((value_t){.v_float = 1.1f}.v_int)),
VARIABLE_DEF("Variable 2", ((value_t){.v_float = 2.2f}.v_int)),
};
(Untested)
On second thought, how about defining a more flexible alternative to VARIABLE_DEF
and using that when needed?
Something like
#define VARIABLE_DEF_ALT(Name, Value) {Name, {Value}}
#define VARIABLE_DEF_ALT2(Name, Field, Value) {Name, {.Field = Value}}
variable my_variables[2] = {
VARIABLE_DEF_ALT("Variable 1", .v_float = 1.1f),
VARIABLE_DEF_ALT2("Variable 2", v_float, 2.2f),
};
should work.
Or just skip the macro:
variable my_variables[2] = {
{"Variable 1", {.v_float = 1.1f}},
{"Variable 2", {.v_float = 2.2f}},
};
— is that actually the macro, or are you simplifying a much more complicated case for this discussion?
Upvotes: 2
Reputation: 98338
You cannot use a function like that from Michael Kerlin's answer in the code, because function call cannot be used in initializers.
But you can write a program that does such a conversion and then copy/paste the resulting integer value into your program! (with a nice comment saying what value it really is).
Upvotes: 0
Reputation: 143061
Maybe a function like static int f(float x) { return *(int*)&x; }
would do?
Upvotes: 0