3 ms·
> Obviously, if argc == 0, you should not dereference anything in argv. Quoting ISO C17: > argv[argc] shall be a null pointer. Not constrained on argc being
by planede 3y ago
> Obviously, if argc == 0, you should not dereference anything in argv.
Quoting ISO C17:
> argv[argc] shall be a null pointer.
Not constrained on argc being greater than zero (unlike the points that follow).
So argv should always be dereferenceable within the program. It's an other question if this should be enforced by the Linux kernel or the C runtime.
https://cigix.me/c17#5.1.2.2.1.p2 https://cigix.me/c17#5.1.2.2.1.p2
- JdeBP 3y agoYou are looking at the wrong standard. Look at the one for the operating systems' APIs.
- planede 3y agoIf you are writing a C program, then you should consult the C standard, and possibly POSIX. The Linux kernel + C runtime + C compiler should form a conforming implementation of the C language. Now if the Linux kernel doesn't promise to pass a non-NULL argv (and documents so), then it should be the responsibility of the C runtime to fix that once the program reaches "main". But as I wrote earlier, it's a whole other question.
- JdeBP 3y agoSo now go and actually consult the POSIX standard, as I just said. You clearly haven't.
- masfuerte 3y agoSo I just looked at the POSIX standard for the exec functions. It says the argv array is terminated by a null pointer when it arrives at the C main function. But a null argv doesn't cause exec to fail. Which implies that the OS or C runtime must fix it up between exec and main.
- planede 3y agoI assume you looked up [0]. > [under int main (int argc, char *argv[]);] The argv and environ arrays are each terminated by a null pointer. The null pointer terminating the argv array is not counted in argc. This confirms that the argv function parameter of main cannot be null. I couldn't find the behavior specified for passing null for argv in exec*. As other comments pointed out some BSDs return with EINVAL. I think both this and Linux's behavior is compliant. [0] https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html https://pubs.opengroup.org/onlinepubs/9699919799/functions/e...
- masfuerte 3y agoYou're right. I misread the list of errors as exhaustive.
- roblabla 3y agoWhy does it even matter what the POSIX standard says? The C standard dictates that `argv[argc] == NULL`, and hence argv shall always be differentiable. Thus, it is very clear that the C standard was violated by the previous Linux+crt. What POSIX says is entirely irrelevant here - if I write a standard C program, not a POSIX program, and it fails to run on the platform, then that platform has violated the C Standard.
- planede 3y agoConversely the C parts of the POSIX standard is supposed to be a conforming extension to ISO C. POSIX even spells this out. https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap01.html#tag_14_01 https://pubs.opengroup.org/onlinepubs/9699919799/functions/V...
- JdeBP 3y agoBecause you haven't grasped it either. No-one is saying that argv[argc] != NULL. But in the case being discussed by M. Siebennmann, argc is 0. The Single Unix Specification says, very clearly: > The argument arg0 should point to a filename string that is associated with the process being started by one of the exec functions. > The value in argv[0] should point to a filename string that is associated with the process being started by one of the exec functions. Then it goes on at length in the rationale at the bottom of that same section about "the use of the word should" and even explains how programs are tripped up by argc being 0. As you can see, both masfuerte and planede have still clearly not read this, despite that it's said twice in the description, and then has two entire paragraphs devoted to the reasoning underpinning it in the rationale.
- planede 3y agoWhile we are at it [0]: > The meanings specified in POSIX.1-2017 for the words shall, should, and may are mandated by ISO/IEC directives. By those directives "should" indicates recommendation. [1] > In POSIX.1-2017, the word should does not usually apply to the implementation, but rather to the application. Thus, the important words regarding implementations are shall, which indicates requirements, and may, which indicates options. You also have to differentiate between any requirements for the argv argument when passed to one of the exec functions and the argv parameter received in main. Any requirement for the former constrains the application, but requirements for the latter constrains the implementation. exec is indeed only documented in POSIX and OS specific documentations, but main is also documented in ISO C. Both POSIX and ISO C constrains the argv parameter of main not to be null. They don't require argc > 0 or argv[0] != null. From [2]: > [under exec] The argument argv is an array of character pointers to null-terminated strings. This is a hard requirement, without "should". This implies that argv must not be null itself when passed to exec. This probably gives implementations the freedom to do whatever in this case, POSIX doesn't define the behavior. The requirement for argv[0] (which implies argc > 0) is merely a recommendation. [0] https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap01.html https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd... [1] https://www.iso.org/foreword-supplementary-information.html https://www.iso.org/foreword-supplementary-information.html