Reputation: 1
I'm fairly new to C, feel free to educate...
I am working with a function that is expecting a pointer to a char array as an input. It is quite cumbersome to individually set each element of the array before its call. I have found a couple of alternatives that appear to work, but am concerned that I am stepping into a trap. Below are a couple of options.
Option 1:
unsigned char DataToPass[8];
uint64_t *IntPtr = (uint64_t *)DataToPass;
...
*IntPtr = 0x1122334455667788;
FunctionCall(DataToPass);
Option 2:
unsigned char DataToPass[8];
uint64_t IntData;
...
iDataToPass = 0x1122334455667788;
memcpy(DataToPass, &IntData, sizeof(IntData);
FunctionCall(DataToPass);
Upvotes: 0
Views: 80
Reputation: 141628
Example 1 may cause undefined behaviour due to alignment violation. Also it causes UB by violating the strict aliasing rule.
Example 2 does not cause UB, however it has implementation-defined result. DataToPass[0]
would be 0x88
on common systems, but 0x11
and 0x55
also exist, and in fact anything is possible.
My advice would be to write code that clearly expresses your intent:
unsigned char DataToPass[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
It'll take you, what , 10 seconds to type but will save a lot of pain.
Upvotes: 3
Reputation: 71090
This is a bit dirty but you could use a union.
union Data
{
char c [8];
uint64_t i;
};
void Func (char *data);
void test ()
{
Data d;
d.i = 0x1122334455667788;
Func (d.c);
}
I think that'd work. Doesn't get around endian problems though.
(I feel I need to have a really thorough wash now)
Upvotes: 1
Reputation: 225032
Both of your examples are fine - with one caveat. You need to ensure that DataToPass
is correctly aligned for your system in order for Option 1 to work correctly. Option 2 is fine as is. If you're really looking to type less, why not:
uint64_t IntData = 0x1122334455667788;
FunctionCall((unsigned char *)&IntData);
As @Barmar mentions in his comment, endianness of your system will play a role here as well.
Upvotes: 2