Hi all,
I am trying to find a way to cast a value to a union type without the use of a dummy variable. My union definition is something like
typedef union _MY_UNION { unsigned long u32; unsigned int u16; unsigned char u8; signed long s32; signed int s16; signed char s8; float fl; } my_union;
I have discovered that I can assign a value to the union at initialization using a line like
my_union z = { 0 };
which works fine. It assumes the first union member as the type of the assignment, so ends up doing the same thing as
my_union z; z.u32 = 0;
except in a much cleaner fashion.
Now for the tricky part -- I have a function that accepts this union type, i.e.
void do_union(my_union u) { ... }
and I would like to be able to call this function without having to pass through a dummy variable first, i.e.
do_union(z); // works as expected, given the definition of z above do_union(0); // C193 incompatible operand do_union((my_union)0); // C215 illegal type conversion do_union((my_union){0}); // C141 syntax error near '{' (as expected; this is initialization syntax)
I get the exact same errors if I use a variable of any member type (including the first) instead of the constant 0. The only way I have been able to get this to work is to use a dummy union variable, i.e.
unsigned long i; my_union t; [...] t.u32 = i; do_union(t);
Is there any way to get around this, and let me call the function directly without the use of a dummy variable?
Regards, -Scott
But wait a minute.
The compiler may already have such a magic construct. I think it is sometimes called unsigned. For people who want to be a bit more fancy pants, they may be called uint32_t (after inclusion of stdint.h).
The receiving end can pick up this 32-bit general-purpose value. Store it in a register and optionally transmit it further. The code can perform bit operations or use the parameter for strchr() calls or enumerators or a large number of other things. The language standard have allready catered for the ability to call functions with const values, without the need for initializing any temporary variables. They are atomic for most 32-bit processors (unless possibly with 8- or 16-bit memory subsystems). They have very good support for code optimization - many compilers specifically have the ability to track the usage pattern and sometimes move the contents from memory to registers, and sometimes from registers to memory. And to analyze life span to let multiple such magic containers share the same register and/or memory region in different parts of a function.
The language standard does describe rules for initializing such a magic construct with signed or unsigned values of smaller size. Many 32-bit architectures also manages to efficiently and sometimes totally transparently transpose these magic containser between integer form and pointer form. Oh joy, to store 0 to the container or to be able to test if (!magic_container) without first having to figured out if the magic container is expected to store a pointer or a numeric entity.
I'm not sure if someone may have any patents on the "unsigned" construct, but I haven't seen any royalty requirements, so I can't see why it shouldn't be presented for a larger audience as a very valuable tool. Some people might even consider it a basic building block - like the characters in our alphabet.