Re: getopt in linux

From: Matthew Hails (matthew_at_nospam.nospam)
Date: 07/22/03


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>


Relevant Pages

  • Re: Problem with va_ macros and arrays of arrays
    ... > the arrays passed to a ... > specific char, somewhat similar to what the standard function ... that with an array of struct, or possibly a pointer to a dynamic array ... > As I'm still a beginner in C without a copy of the standard I ...
    (comp.lang.c)
  • Re: fgetc
    ... argv is declared as array of pointer to char. ... it's declared as a pointer to pointer to char. ... "Neither compiler yet handled the general declaration syntax of today or ...
    (comp.lang.c)
  • Re: fgetc
    ... argv is declared as array of pointer to char. ... it's declared as a pointer to pointer to char. ... "Neither compiler yet handled the general declaration syntax of today or ...
    (comp.lang.c)
  • Re: Difference between Char* ptr and char arrCh []
    ... I have a few queries regarding array of characters using array ... notation and pointer notation. ... Is there a difference in storage of global char* and char* inside ...
    (comp.lang.c)
  • Re: Returning pointer to array problem II
    ... Iam trying to make program were I enter string and serach char. ... and funktion prints out witch position char is found this is done if funktion serach_char. ... so far all good what I want do next is: return, from funktion, pointer value to array were positions is stored. ...
    (comp.lang.c)