main argument curiosity

S

Stephen Mayes

Correct me if I am mistaken.
The C standard guarantees that in a C hosted environment we can define main
as:
int main( int argc, char *argv[] ).

I always assume that 'argc' is the number of pointers in the array 'argv'
and that the pointers in 'argv' point to null-terminated strings, and that
those strings represent a command line.

Is this always the case?
Do the standards say so?
 
S

Simon Biber

Stephen Mayes said:
Correct me if I am mistaken.
The C standard guarantees that in a C hosted environment we can
define main as:
int main( int argc, char *argv[] ).

Yes, without the full stop, and with braces to indicate a
function definition.
I always assume that 'argc' is the number of pointers in the array
'argv' and that the pointers in 'argv' point to null-terminated
strings, and that those strings represent a command line.
Is this always the case?

If argc is not zero, then the array members argv[1] through to
argv[argc - 1] point to null-terminated strings with an
implementation-defined value, representing the "program parameters".

On computers where there is such a thing as a command line, and the
program is invoked in such a way as to supply a command line, then
any command line arguments are usually supplied in this way.

Some operating systems do not have the concept of command line
arguments, whereas some other operating systems have multiple
ways to invoke a program, some of which allow specifying program
parameters and some of which do not.
Do the standards say so?

C99 5.1.2.2.1 Program Startup, paragraph 2
If they are declared, the parameters to the main function shall
obey the following constraints:
- The value of argc shall be nonnegative.
- argv[argc] shall be a null pointer.
- If the value of argc is greater than zero, the array members
argv[0] through argv[argc-1] inclusive shall contain pointers
to strings, which are given implementation-defined values by
the host environment prior to program startup. The intent is
to supply to the program information determined prior to
program startup from elsewhere in the hosted environment. If
the host environment is not capable of supplying strings with
letters in both uppercase and lowercase, the implementation
shall ensure that the strings are received in lowercase.
- If the value of argc is greater than zero, the string pointed
to by argv[0] represents the program name; argv[0][0] shall be
the null character if the program name is not available from
the host environment. If the value of argc is greater than one,
the strings pointed to by argv[1] through argv[argc-1]
represent the program parameters.
- 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.
 
C

Christopher Benson-Manica

Simon Biber said:
If argc is not zero, then the array members argv[1] through to
^^^^^^^
ITYM argv[0] here, yes?
C99 5.1.2.2.1 Program Startup, paragraph 2
argv[0] through argv[argc-1] inclusive shall contain pointers

Yes. ;)
 
R

Richard Bos

Christopher Benson-Manica said:
Simon Biber said:
If argc is not zero, then the array members argv[1] through to
^^^^^^^
ITYM argv[0] here, yes?

No. He said that argv[1] through argv[argc-1] point to the program
parameters. argv[0] points to a string, but it doesn't contain parameter
- it contains the program name (or at least some approximation to it).

Richard
 
C

Christopher Benson-Manica

Richard Bos said:
If argc is not zero, then the array members argv[1] through to
^^^^^^^
ITYM argv[0] here, yes?
No. He said that argv[1] through argv[argc-1] point to the program
parameters. argv[0] points to a string, but it doesn't contain parameter
- it contains the program name (or at least some approximation to it).

He did, because if argc is one (i.e., not zero), argv[1] is still not
going to point to anything (or at least it certainly isn't required
to).
 
D

Dan Pop

In said:
Richard Bos said:
If argc is not zero, then the array members argv[1] through to
^^^^^^^
ITYM argv[0] here, yes?
No. He said that argv[1] through argv[argc-1] point to the program
parameters. argv[0] points to a string, but it doesn't contain parameter
- it contains the program name (or at least some approximation to it).

He did, because if argc is one (i.e., not zero), argv[1] is still not
going to point to anything (or at least it certainly isn't required
to).

If argc is one, argv[1] is *guaranteed* to be a null pointer. This is
a general property of argv[argc], regardless of the value of argc, because
the argv "array" uses a null pointer as sentinel value. This is not very
useful for argv, because of argc, but it's quite useful to envp (on
implementations supporting it), because it has no associated count
parameter.

Dan
 
C

Christopher Benson-Manica

Dan Pop said:
If argc is one, argv[1] is *guaranteed* to be a null pointer. This is
a general property of argv[argc], regardless of the value of argc, because
the argv "array" uses a null pointer as sentinel value. This is not very
useful for argv, because of argc, but it's quite useful to envp (on
implementations supporting it), because it has no associated count
parameter.

Thanks for clarifying. So when argc is 1, would you say that argv[1]
points to a program parameter? Is a null pointer a pointer to a
program parameter?
 
D

Dan Pop

In said:
Dan Pop said:
If argc is one, argv[1] is *guaranteed* to be a null pointer. This is
a general property of argv[argc], regardless of the value of argc, because
the argv "array" uses a null pointer as sentinel value. This is not very
useful for argv, because of argc, but it's quite useful to envp (on
implementations supporting it), because it has no associated count
parameter.

Thanks for clarifying. So when argc is 1, would you say that argv[1]
points to a program parameter? Is a null pointer a pointer to a
program parameter?

Obviously not. When argc is 1, the *only* information available in argv
is the program name. The standard is crystal clear:

If the value of argc is greater than one, the strings pointed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
to by argv[1] through argv[argc-1] represent the program
parameters.

Dan
 
C

Christopher Benson-Manica

Dan Pop said:
Obviously not. When argc is 1, the *only* information available in argv
is the program name. The standard is crystal clear:
If the value of argc is greater than one, the strings pointed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
to by argv[1] through argv[argc-1] represent the program
parameters.

Thanks. Then that means that the statement that led me along this
ill-advised path,
(Simon Biber said long ago, elsethread)
If argc is not zero, then the array members argv[1] through to
argv[argc - 1] point to null-terminated strings with an
implementation-defined value, representing the "program parameters".

should been "If argc is greater than 1...", correct?
 
D

Dan Pop

In said:
Dan Pop said:
Obviously not. When argc is 1, the *only* information available in argv
is the program name. The standard is crystal clear:
If the value of argc is greater than one, the strings pointed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
to by argv[1] through argv[argc-1] represent the program
parameters.

Thanks. Then that means that the statement that led me along this
ill-advised path,
(Simon Biber said long ago, elsethread)
If argc is not zero, then the array members argv[1] through to
argv[argc - 1] point to null-terminated strings with an
implementation-defined value, representing the "program parameters".

should been "If argc is greater than 1...", correct?

I think someone promptly corrected his statement. I've no idea where
he was quoting from.

The things are very simple: argv[argc] is always a null pointer. If the
value of argc leaves room for other array elements, the first is the
program name (or an empty string if the program name is not available)
and the rest are program parameters.

Dan
 
C

Christopher Benson-Manica

I think someone promptly corrected his statement. I've no idea where
he was quoting from.

I attempted to correct the statement; as you've shown, it was a poor
attempt, for which I apologize. The original statement, however, was
not correct, and my news server does not show any other replies to the
post in question.
 
O

Old Wolf

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

Supposing that main() exits via the return statement, does this mean
implementation must not pop the stack before running the atexit()
functions? (in case there was global references to argc or argv)
 
C

Christopher Benson-Manica

Old Wolf said:
Supposing that main() exits via the return statement, does this mean
implementation must not pop the stack before running the atexit()
functions? (in case there was global references to argc or argv)

Among other things, the implementation should definitely not pop the
stack if it isn't using a stack. :)
 
D

Dan Pop

In said:
Supposing that main() exits via the return statement, does this mean
implementation must not pop the stack before running the atexit()
functions? (in case there was global references to argc or argv)

Nope, main() has the semantics of any other C function. Once main()
has returned, its parameters are gone. Instead of having global pointers
to argc and argv, it's even simpler to store the actual values of argc and
argv in globals. The array of strings itself is allocated outside of
main(), so returning from main() is not affecting it in any way and
atexit-registered functions can access it without any problems, if they
know its address.

The issue is addressed by a footnote in C99:

5.1.2.2.3 Program termination

1 If the return type of the main function is a type compatible
with int, a return from the initial call to the main function is
equivalent to calling the exit function with the value returned
by the main function as its argument;10) reaching the } that
terminates the main function returns a value of 0. If the return
type is not compatible with int, the termination status returned
to the host environment is unspecified.
____________________

10) In accordance with 6.2.4, the lifetimes of objects with
automatic storage duration declared in main will have ended in
the former case, even where they would not have in the latter.

The main() parameters are objects with automatic storage duration
declared in main().

Dan
 
O

Old Wolf

- The parameters argc and argv and the strings pointed to by the
The issue is addressed by a footnote in C99:
10) In accordance with 6.2.4, the lifetimes of objects with
automatic storage duration declared in main will have ended in
the former case, even where they would not have in the latter.

The main() parameters are objects with automatic storage duration
declared in main().

This doesn't seem to be compatible with the section mentioned above.
At a point after main() has returned but before the program has
terminated, then the footnote says argc and argv no longer exist,
but the topmost quote says that they must exist at that point.
 
D

Dan Pop

In said:
This doesn't seem to be compatible with the section mentioned above.
At a point after main() has returned but before the program has
terminated, then the footnote says argc and argv no longer exist,
but the topmost quote says that they must exist at that point.

The purpose of the footnote is to clarify what the people who wrote the
standard *actually* meant to say. You're free to ignore the footnote,
but you're running the risk that the implementor of your compiler didn't.

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,137
Messages
2,570,797
Members
47,345
Latest member
tektheone

Latest Threads

Top