Re: getopt in linux
From: Matthew Hails (matthew_at_nospam.nospam)
Date: 07/22/03
- Next message: ehab: "undefined symbol identification problem"
- Previous message: David Schwartz: "Re: How to ignore SIGSEGV signal"
- In reply to: Floyd Davidson: "Re: getopt in linux"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Tue, 22 Jul 2003 08:19:49 GMT
Floyd Davidson wrote:
> Matthew Hails <matthew@nospam.nospam> wrote:
>
> >>Floyd Davidson wrote:
> >
> >>>> Matthew Hails <matthew@nospam.nospam> wrote:
> >>
> >>>>> >Floyd Davidson wrote:
> >>>
> >>>>>> >> The parameter list for getopt() looks like,
> >>>>>> >>
> >>>>>> >> int getopt(int argc, char * const argv[], const char *optstring);
> >>>>>> >>
> >>>>>> >> Note the second parameter is not a pointer to pointer to char,
> >>>>>> >> but rather an array of pointers to char (or, more easily
> >>>>>> >> understood, it is an array of pointers to strings). It should
> >>>>>> >> be declared as char opt1[], not char **op1.
> >>>
> >>>>> >
> >>>>> >To be pedantic ...
> >>
> >>>>
> >>>> I don't think you actually said anything different than what
> >>>> I did, except that you are applying the same terms to different
> >>>> objects than I did.
> >
> >>
> >>Ok, there's some truth in that. Let me explain my "terms" more fully:
> >>
> >>The formal parameter type is:
> >> pointer to pointer to char
>
> If you mean the parameter list of the declaration, *look* at the
> above declaration, which is "char * const argv[]". That is a
> pointer to an array of pointers to char, not a pointer to
> pointer to char. (I'm ignoring the "const" in this discussion
> to reduce confusion.)
You are nearly(*) correct in a sense. (Sadly I wandered into this
discussion claiming to be pedantic, but haven't been pedantic enough in my
explanations). The second parameter is declared as an array of pointer to
char, but is immediately converted to a pointer to pointer to char. (I
think we're agreed to ignore the "const" for this discussion!). The C99
standard says:
"A parameter declared to have array or function type is converted to a
parameter with a pointer type as described in 6.9.1." [6.5.2.2]
"A declaration of a parameter as 'array of type' shall be adjusted to
'qualified pointer to type' ... " [6.7.5.3]
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as if
by assignment. (Array expressions and function designators as arguments
were converted to pointers before the call.)" [6.9.1]
So we see that:
(1) The declaration of the parameter is converted from "array of pointer to
char" to "pointer to pointer to char".
(2) On calling the function, the actual argument, if of type "array of
pointer to char", is converted to "pointer to pointer to char" before
being passed.
Indeed, if I look on my machine (vanilla RedHat 8.0), the man page has
the second parameter as "char * const argv[]" (the same as you quoted),
but in the system header files it is declared as:
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
> >>>>> >Technically the second parameter *is* a pointer to (a const) pointer to
> >>>>> >char.
> >>
> >>>>
> >>>> Not in the prototype/declaration above!
> >
> >>
> >>I disagree! It may look like it is, because it uses [], but really it's a
>
> Array types are distinct from pointer types. That really is an
> array type, because it does use the [] syntax.
True. What I said there wasn't strictly correct. (But see above).
> Array objects and pointers objects are NOT the same thing.
I agree!
> >>Try passing an array of pointers to char into
>
> First, for the parameter list in a declaration, when comparing
> functions for compatibility, yes the array type will first be
> converted to a pointer type before determining if the types are
> compatible.
>
> Second, when a function call is made, the argument list holds
> the identifiers of objects listed, and that in this case would
> include the name for an array object. However, before the
> actual function call is made the identifier for the array object
> will be converted to a pointer to the first element of that
> object.
>
> None of which means that "really it's a pointer type, not an
> array". It is an array, and in specific situations it is
> specifically converted to a pointer.
Ok, I concede that the formal parameter does have array type. But - it is
converted into a pointer type before it can have any effect on a caller of
the function.
> I was being pedantic. :-)
Argghhh - impaled on my own words :-)
Perhaps I can try and summarise:
1. I agree that you were correct in saying that:
The formal parameter really does have array type.
(And I was wrong to say that it *does have* pointer type)
2. However, my contention is (and this is how I should have (pedantically!)
explained it the first time):
The formal parameter is converted to a pointer type, and therefore the
array type declaration has no more effect than documenting that the
function expects the pointer to access an array rather than a single
object.
This is why glibc can merrily document that it is an array type but
really declare it as a pointer type.
(*) I say "nearly", because you said "pointer to an array of pointers to
char". If we're discussing exactly what the declared type is, then it's
not a pointer type yet, but simply an "array of pointers to char".
Of course, later on in the discussion you do say it's an array type, so
I'll assume that's what you meant in this first instance.
(Phew! :-)
-- Matthew Hails <matthew@hails.org.uk>
- Next message: ehab: "undefined symbol identification problem"
- Previous message: David Schwartz: "Re: How to ignore SIGSEGV signal"
- In reply to: Floyd Davidson: "Re: getopt in linux"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|