Reputation: 159
I have to write some literals to an array, but I have just the address of the array, so I'm doing it by first creating a local array, filling it with the literals and second copy the content to the destination array. Here is an example:
void example(char *array) {
char temp[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
memcpy(array, temp, sizeof(temp));
}
This works pretty fine, but I'm searching for a way to do the same within one line instead of two. Has anyone an idea how to do this?
Upvotes: 2
Views: 98
Reputation: 15176
Assuming machine is LSB
*(unsigned long long *)array = 0x0807060504030201;
P.S. Well, don't take it too serious ;-)
P.P.S. Let me throw in another argument against using char[]
(instead of static char[]
) inside function.
Although the optimizing compiler can sometimes rule out the annoying stack variable, but it's not always possible. Consider, for example, invoking some other function, say, printf("%s", temp)
. It looks quite innocent, yet, as the second argument to printf
is not known as const
, the compiler must create the copy of the whole array temp
on the stack, before passing it to printf
.
For some large array, this could be really painful!
Upvotes: 1
Reputation: 145889
You can use a compound literal:
memcpy(array, (char []) {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
sizeof ((char []) {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}));
You can use a define to not have to repeat the array (this is more error-prone if you have to modify the array elements):
#define ARRAY ((char []) {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08})
memcpy(array, ARRAY, sizeof ARRAY);
Upvotes: 2
Reputation: 214187
The canonical way to write the code would be this:
void example(char *array) {
static const char temp[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
memcpy(array, temp, sizeof(temp));
}
This is very readable and also the fastest possible, since the local constant will not be allocated on the stack per function call. But of course, that's something that the compiler will likely optimize anyhow.
There is no reason what-so-ever to attempt to manually optimize this code further. String literals will make the code harder to read. Compound literals will have local scope and are in theory allocated on the stack for each function call, which would make the code slower in theory - in practice the compiler will likely optimize the compound literal so that it isn't pushed on the stack for each function call.
If several functions need to use the same constant, then declare it at file scope, but keep it static const
so that you don't clutter down the global namespace more than necessary.
Upvotes: 2
Reputation: 23680
I'm writing this answer down because you commented that you want to do it in one line in order to avoid having "to access many pointers". But you won't. Any decent compiler will optimize this. GCC with -O1
produces this code on x86_64
for your example, unchanged. It doesn't even call memcpy
:
example:
.LFB12:
.cfi_startproc
movb $1, (%rdi)
movb $2, 1(%rdi)
movb $3, 2(%rdi)
movb $4, 3(%rdi)
movb $5, 4(%rdi)
movb $6, 5(%rdi)
movb $7, 6(%rdi)
movb $8, 7(%rdi)
ret
.cfi_endproc
To explain: $1
, $2
etc are elements of your literal, and %rdi
is the register that contains the first argument to example
i.e. the pointer you named array
.
Just use the two readable lines.
Upvotes: 5
Reputation: 2233
This is less readable than your code, I'd say, but if you simply must do it in one line...
memcpy(array, "\x01\x02\x03\x04\x05\x06\x07\x08", sizeof("\x01\x02\x03\x04\x05\x06\x07\x08") - 1);
Upvotes: 3