while preparing to the end of semester exam I have stumbled upon the following question: Given this piece of code:
#include <stdio.h>
int main() {
const char *const ptr1[] = {"to be", "or not to be", "that is the question"};
char *ptr2 = "that is the question";
(&ptr2)[3]="hamlet";
for (int i = 0; i < sizeof(ptr1) / sizeof(*ptr1); i)
printf("%s ", ptr1[i]);
return 0;
}
prints the following: "to be hamlet that is the question"
I thought that this code wouldn't compile.
However, the code compiles.
can someone please help me understand why does this code behave like that ?
CodePudding user response:
It will probably compile, since there is nothing in the code that would require the compiler to diagnose a problem.
The assignment works in the sense that the types are correct. ptr2 has type char*, so &ptr2 has type char** and (&ptr2)[3] has type char*, which we can assign a string literal.
However, ptr2 is not an array, so accessing it at offset 3 is not possible. The program has undefined behavior and it doesn't make sense to claim a specific output.
Enable warnings and sanitizers when compiling the program and see what is wrong: https://godbolt.org/z/G67j6qr7a
CodePudding user response:
The code compiles, the assignment itself is valid as far as C language syntax and constraints go. However, it invokes undefined behavior (see What is undefined behavior and how does it work?) since you access the variable ptr2 out of bounds - which is nonsense. I don't get that output which you claim on my compiler, simply because there is no deterministic outcome from this code.
On some systems the out of bounds access might generate an access of the previously declared array on the stack, but there are no guarantees of such behavior. Most systems have down-counting stacks, so I don't think a lot of them would end up modifying the pointer array as assumed. In addition the compiler is free to allocate ptr1 and ptr2 at any addresses in relation to each other.
