Command line arguments in C, cant understand its b

2019-06-02 19:17发布

I've the following code :

#include <stdio.h>
int main(int argc, char* argv[]){
    int a = argv[1]?atoi(argv[1]):10;
    int b = argv[2]?atoi(argv[2]):20;
    printf("a = %d, b = %d\n", a, b);
    return 0;
}

If I do not provide any command line inputs, the values in "a" and "b"
should be 10 and 20 respectively, but what happens instead is "a" gets value as 10 whereas "b" gets 0.
I cant understand why this is happening, since I am doing exactly same
thing in both cases.

Thanks.

2条回答
聊天终结者
2楼-- · 2019-06-02 19:33

The runtime (often thru crt0 & kernel) guarantees (per C99 or POSIX standards) that (for main's arguments argc & argv) :

  • argc is positive

  • argv is a valid non NULL pointer to an array of argc+1 pointers

  • argv[argc] is the NULL pointer

  • for each i between 0 and argc-1 included, argv[i] is a (valid non NULL) pointer to a zero-terminated string

  • hence access to argv[j] with j>argc (or j<0) is undefined behavior (UB) - so explaining what happens is only possible by diving into implementation details...

  • the valid argv[i] are not pointer aliases, so if i & j are both between 0 and argc-1 included, and i != j, argv[i] != argv[j]

therefore, your code is wrong when argc==1 because accessing argv[2] is forbidden (UB).

You should code:

int main(int argc, char* argv[]){
    int a = (argc>1)?atoi(argv[1]):10;
    int b = (argc>2)?atoi(argv[2]):20;

Be very scared of undefined behavior (see also the references here). Sadly, a program with UB might sometimes appear to "work" (that is might not crash). But at other times bad things may happen. So you should imagine the worst.

查看更多
闹够了就滚
3楼-- · 2019-06-02 19:51

If I do not provide any command line inputs, the values in "a" and "b" should be 10 and 20 respectively.

No, if you don't provide any command-line inputs, you're accessing beyond the end of the argv array and anything can happen (including your program crashing and burning).

Your checks should be:

int a = argc > 1 ? atoi(argv[1]) : 10;
int b = argc > 2 ? atoi(argv[2]) : 20;

That's what argc is for, to tell you how many entries argv has in it that you can access.

查看更多
登录 后发表回答