4

I see the main() function usually called as:

  • int main(int argc, char** argv)
  • int main(int argc, char* argv[])
  • int main(void)

Related to these definitions:

  1. Technically speaking, for char** argv and char* argv[] is one preferred over the other or are these 100% interchangeable?
  2. Because both the argc and argument strings (should be?) immutable, why aren't they both const ? Or is this something that doesn't matter and it's just omitted out of convention/historical purpose? I suppose this could be done with: const char **argv = (const char **) argv; but curious why this isn't already done (would there be reasons for changing the arguments that are received, for example?)
David542
  • 104,438
  • 178
  • 489
  • 842
  • Does this answer your question? [Why is argc not a constant?](https://stackoverflow.com/questions/20558418/why-is-argc-not-a-constant) – Sprite Sep 21 '20 at 19:53
  • 1) they are 100% absolutely identical 2) argv parameters are not immutable ... I'd frown upon "extending" them though .. `argv[1][len = strlen(argv[1])] = '*'; argv[1][len+1] = 0;` – pmg Sep 21 '20 at 19:53
  • 1
    @Sprite yea that's good, but the issue is one is tagged `C` and the other `C++` -- maybe have the duplicate tagged with both C and C++ ? – David542 Sep 21 '20 at 19:55
  • 3
    About `argc` there isn't much reason to declare a value argument as `const` in general. That would also invalidate the pretty idiomatic `while(argc--) printf("%s\n", *argv++);`. – dxiv Sep 21 '20 at 19:57
  • 1
    See also [Is `argv[n]` writable?](https://stackoverflow.com/q/25737434/2410359). – chux - Reinstate Monica Sep 22 '20 at 02:17
  • @chux-ReinstateMonica thanks, could you share the link that you use to view the C-spec? – David542 Sep 22 '20 at 04:32
  • [Where do I find the current C or C++ standard documents?](https://stackoverflow.com/q/81656/2410359) – chux - Reinstate Monica Sep 22 '20 at 10:56
  • @chux-ReinstateMonica thanks so much. So odd that it's not free... – David542 Sep 22 '20 at 17:22

3 Answers3

5

Because they are both modifiable:

N1570 §5.1.2.2.1/2:

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.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • ok, what might be a reason that a program might want to modify them? – David542 Sep 21 '20 at 19:54
  • 4
    Why not? an example: you want to replace commas with dots when numbers are passed, transform to lower/upper case, remove/replace an extension ... there are many reasons to modify a string – David Ranieri Sep 21 '20 at 19:58
  • 1
    I took advantage of that just recently. I wanted to remove commas from a numeric string that I was copy/pasting from an external source, and it was easy to do that in-place rather than creating another string. – Weather Vane Sep 21 '20 at 20:18
  • @DavidRanieri thanks. Could you please share a link to the C standard file/html doc that has what you've listed above? – David542 Sep 22 '20 at 02:28
  • Of course: https://port70.net/~nsz/c/c11/n1570.html – David Ranieri Sep 22 '20 at 04:35
  • Note that `argc`, `argv` and `argv[][]` are modifiable per this cite. `argv[]` is the [unclear](https://stackoverflow.com/q/25737434/2410359) part. – chux - Reinstate Monica Sep 22 '20 at 11:05
2
  1. They are completely interchangeable.
  2. It is valid to modify them, sometimes there is a chain of command line processors in a program, and each removes the options relevant to it, before passing it on tho the next processor of the chain. In this case argc is passed into the processors via pointer. You can see an example, not in C but in C++ in the QT library: QApplication constructor.
g_bor
  • 1,077
  • 6
  • 14
1

There's a long discussion of the distinction (or non-distinction) between *argv[] and **argv here:

Should I use char** argv or char* argv[]?

Both are fairly widely used, and there's no practical difference between them in this particular context.

As for whether the pointers should be const are not -- that's an interesting, but rather academic debate. I'm a great believer in const-correctness in C, but main() is one place where I think it's counter-productive. It's idiomatic to write char **argv whether these pointers are really const or not, or whether your code treats them as constants or not. On Linux, they actually aren't constant -- a program can modify them, although there's rarely a need to.

My feeling is that if you write anything but char **argv or char *argv[], it's just going to cause confusion. I've recently seen examples where main() is defined to take char *argv[argc+1]. This is permissible with modern C compilers, but it's just not something C programmers are used to seeing.

Kevin Boone
  • 4,092
  • 1
  • 11
  • 15
  • 3
    The pointers in `argv` and the strings they point to are not `const`, period. There is no debate. See the quote from the C standard in [David's answer](https://stackoverflow.com/a/63999119/3386109). Also, `char *argv[argc]` is wrong. The actual size of the array is `argc+1`, since the C standard requires a NULL pointer at the end of the `argv` array. – user3386109 Sep 21 '20 at 20:13
  • 2
    *that's an interesting, but rather academic debate* It's not an academic discussion **at all**. By the C standard, both `argc` and the pointer value in `argv` *and* the strings referred to by those pointers shall all be modifiable by the program. – Andrew Henle Sep 21 '20 at 20:14
  • 1
    It's academic because indicating whether something is technically modifiable or not is not what const-correctness is about. If I define a function as `void foo (const char *bar)` I'm not preventing the function from modifying `bar` because something in the platform would disallow it, or because it's actually constant in the caller. I'm using `const` to indicate that my function does not, in fact, modify `bar` via its pointer -- that it would be an error if I wrote code to do so. The compiler will not complain if I declare `argv` to consist of `const` pointers, and some recommend doing so. – Kevin Boone Sep 21 '20 at 20:28