I'm not an x86 guru, but I think that "movq ptr(%rip), %rsi" is different because ptr needs to be moved from relative to the instruction pointer (because it is on the stack, as a non-const variable).
I'm not an x86 guru, but I think that "movq ptr(%rip), %rsi" is different because ptr needs to be moved from relative to the instruction pointer (because it is on the stack, as a non-const variable).
$arr is copying the address of "arr", so it must use an immediate move (possibly 64-bit). It could also use RIP-relative with the "lea" (load effective address) instruction.
$ptr(%rip) is accessing memory, so it uses RIP-relative addressing with the "mov" instruction.
And because it's a const, it's in the .rodata section... (read-only) Playing too liberally with the data often leads to a SEGV (as it should).
So the "do_arr" version "knows" what value is at * arr because "arr" is immutable, so the compiler can just choose to load a constant. The "do_ptr" version has to load from memory instead.
But what if we tell the compiler that the value of "ptr" won't change (i.e. "char * const" instead of "const char * ")? The code becomes the same:
So basically "const char []" and "char * const" are more logically equivalent here.
It's old-fashioned but I assume (maybe others can correct me) the latest edition is up to date enough that it won't teach you any outright bad habits.