Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is argv[n] writable?

C11 5.1.2.2.1/2 says:

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.

My interpretation of this is that it specifies:

int main(int argc, char **argv) {     if ( argv[0][0] )         argv[0][0] = 'x';   // OK      char *q;     argv = &q;              // OK } 

however it does not say anything about:

int main(int argc, char **argv) {     char buf[20];     argv[0] = buf; } 

Is argv[0] = buf; permitted?

I can see (at least) two possible arguments:

  • The above quote deliberately mentioned argv and argv[x][y] but not argv[x], so the intent was that it is not modifiable
  • argv is a pointer to non-const objects, so by in the absence of specific wording to the contrary, we should assume they are modifiable objects.
like image 383
M.M Avatar asked Sep 09 '14 05:09

M.M


People also ask

Can you write to argv?

The syntax char** argv declares argv to be a pointer to a pointer to a character, that is, a pointer to a character array (a character string)--in other words, an array of character strings. You could also write this as char* argv[] .

What is argv N?

argv[n] is not a string; it's a pointer that points to the first character of a string. – M.M. Sep 9, 2014 at 5:54. 2.

Is argv a char?

argv is an array of strings, or say, an array of char * . So the type of argv[1] is char * , and the type of argv[1][0] is char .

Is argv string or char?

The first (conventionally called argc) is the number of command-line arguments the program was invoked with; the second (argv) is a pointer to an array of character strings that contain the arguments, one per string.


1 Answers

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".

like image 162
chux - Reinstate Monica Avatar answered Oct 07 '22 02:10

chux - Reinstate Monica