Lui
Lui

Reputation: 159

Accessing pointer with pointer to a literal

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

Answers (5)

Matt
Matt

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

ouah
ouah

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

Lundin
Lundin

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

ArjunShankar
ArjunShankar

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

Cole Cameron
Cole Cameron

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

Related Questions