Struct vs string literals? Read only vs read-write?

  • A+
Category:Languages

Does the C99 standard permit writing to compound literals (structs)? It seems it doesn't provide writing to literal strings. I ask about this because it says in C Programming: A Modern Approach, 2nd Edition on Page 406.

Q. Allowing a pointer to a compound literal would seem to make it possible to modify the literal. Is that the case?

A. Yes. Compound literals are lvalues that can be modified.

But, I don't quite get how that works, and how that works with string literals which you certainly can't modify.

char *foo = "foo bar"; struct bar { char *a; int g; }; struct bar *baz = &(struct bar){.a = "foo bar", .g = 5};  int main () {   // Segfaults   // (baz->a)[0] = 'X';   // printf( "%s", baz->a );    // Segfaults   // foo[0] = 'a';   // printf("%s", foo);    baz->g = 9;   printf("%d", baz->g);    return 0; } 

You can see on my list of things that segfault, writing to baz->a causes a segfault. But, writing to baz->g does not. Why is that one of them would cause a segfault and not the other one? How are struct-literals different from string-literals? Why would struct-literals not also be put into read-only section of memory and is the behavior defined or undefined for both of these (standards question)?

 


First thing first: your struct literal has a pointer member initialized to a string literal. The members of the struct itself are writeable, including the pointer member. It is only the content of the string literal that is not writeable.

String literals were part of the language since the beginning, while struct literals (officially known as compound literals) are a relatively recent addition, as of C99. By that time many implementations existed that placed string literals in read-only memory, especially on embedded systems with tiny amounts of RAM. By then designers of the standard had a choice of requiring string literals to be moved to a writeable location, allowing struct literals to be read-only, or leaving things as-is. None of the three solutions was ideal, so it looks like they went on the path of least resistance, and left everything the way it is.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: