Is argv[n] writable?

Solution 1:

IMO, code like argv[1] = "123"; is UB (using the original argv).


"The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination." C11dr & C17dr1 §5.1.2.2.1 2

Recall that const came into C many years after C's creation.

Much like char *s = "abc"; is valid when it should be const char *s = "abc";. The need for const was not required else too much existing code would have be broken with the introduction of const.

Likewise, even if argv today should be considered char * const argv[] or some other signature with const, the lack of const in the char *argv[] does not complete specify the const-ness needs of the argv, argv[], or argv[][]. The const-ness needs would need to be driven by the spec.

From my reading, since the spec is silent on the issue, it is UB.

Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior" §4 2


[edit]:

main() is a very special function is C. What is allowable in other functions may or may not be allowed in main(). The C spec details attributes about its parameters that given the signature int argc, char *argv[] that shouldn't need. main(), unlike other functions in C, can have an alternate signature int main(void) and potentially others. main() is not reentrant. As the C spec goes out of its way to detail what can be modified: argc, argv, argv[][], it is reasonable to question if argv[] is modifiable due to its omission from the spec asserting that code can.

Given the specialty of main() and the omission of specifying that argv[] as modifiable, a conservative programmer would treat this greyness as UB, pending future C spec clarification.


If argv[i] is modifiable on a given platform, certainly the range of i should not exceed argc-1.

As "argv[argc] shall be a null pointer", assignining argv[argc] to something other than NULL appears to be a violation.

Although the strings are modifiable, code should not exceed the original string's length.

char *newstr = "abc";
if (strlen(newstr) <= strlen(argv[1])) 
  strcpy(argv[1], newstr);

1 No change with C17/18. Since that version was meant to clarify many things, it re-enforces this spec is adequate and not missing an "argv array elements shall be modifiable".