hubcap@hubcap.UUCP (Mike S Marshall) (09/29/87)
on page 110 of K&R it says: "...(argv) is a pointer to an array of character strings..." but since the primary-expression operator [] has higher priority than the unary operator *, then isn't it more correct to say that argv (which is defined as char *argv[]) is an array of pointers to character strings? -Mike Marshall hubcap@hubcap.clemson.edu ...!hubcap!hubcap
guy%gorodish@Sun.COM (Guy Harris) (09/30/87)
(This is a C question, not a UNIX question.) > on page 110 of K&R it says: > > "...(argv) is a pointer to an array of character strings..." > > but since the primary-expression operator [] has higher priority than > the unary operator *, then isn't it more correct to say that argv > (which is defined as char *argv[]) is an array of pointers to character > strings? No, it is more correct to say that "argv" is a pointer to the first element of an array of pointers to "char", which can be read as "'argv' is a pointer to the first element of an array of pointers to character strings". "argv" is *properly* declared as "char **argv"; however, if you declare an array of type X as an argument to a function, the compiler interprets that as a declaration of a pointer to type X instead. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
kre@munnari.oz (Robert Elz) (09/30/87)
In article <517@hubcap.UUCP>, hubcap@hubcap.UUCP (Mike S Marshall) writes: > k&r: "...(argv) is a pointer to an array of character strings..." > > isn't it more correct to say that argv is an array of pointers to character > strings? Not really, argv is a pointer to an array of pointers to null terminated arrays of characters. A pointer to a null terminated array of characters is what is colloquially callyed a "character string" (eg: "abc" .. which is a pointer to a null terminated array of characters). So k&r's description is right. That argv is a pointer, and not an array is a crucial difference, if argv were an array, "argv++;" would be an illegal statement. kre
gwyn@brl-smoke.UUCP (10/01/87)
In article <517@hubcap.UUCP> hubcap@hubcap.UUCP (Mike S Marshall) writes: >... (which is defined as char *argv[]) ... Actually, due to a funny quirk in C, all correct declarations of the second formal parameter to main() are equivalent to char **argv; Whether you want to consider this as char *argv[]; or char (*argv)[]; doesn't really matter.
eao@anumb.UUCP (e.a.olson) (10/01/87)
> on page 110 of K&R it says: > > "...(argv) is a pointer to an array of character strings..." > > but since the primary-expression operator [] has higher priority than > the unary operator *, then isn't it more correct to say that argv > (which is defined as char *argv[]) is an array of pointers to character > strings? > > -Mike Marshall hubcap@hubcap.clemson.edu ...!hubcap!hubcap The point is that in C, a 'character string' is referred to by a pointer to it.
sarah@laticorp.UUCP (Sarah Groves Hobart) (10/09/87)
In article <517@hubcap.UUCP>, hubcap@hubcap.UUCP (Mike S Marshall) writes: > on page 110 of K&R it says: > > "...(argv) is a pointer to an array of character strings..." > > but since the primary-expression operator [] has higher priority than > the unary operator *, then isn't it more correct to say that argv > (which is defined as char *argv[]) is an array of pointers to character > strings? What is actually being declared is a pointer to an array of pointers. Remember that the following declarations are equivalent: char s[]; char *s; Most people would tend to call the first declaration a character string, and the second a character pointer, but they are the same thing. So K&R are just using slightly different terminology, probably in the interests of clarity. An array of pointers to character strings would be a pointer to an array of pointers to an array of pointers. Sarah Groves Hobart {ihnp4,amdahl,sun}!ptsfa!laticorp!sarah
sarah@laticorp.UUCP (Sarah Groves Hobart) (10/09/87)
In article <321@laticorp.UUCP>, sarah@laticorp.UUCP (Sarah Groves Hobart) writes: > > An array of pointers to character strings would be a pointer to an array > of pointers to an array of pointers. Oops. . . .my fingers just wouldn't stop typing "array of pointers". What I meant was: An array of pointers to character strings would be a pointer to a bunch of pointers of type char. I was trying to point out that "character string" is simply a pointer to a bunch of objects which happen to be chars, as is an array of characters. Sarah Groves Hobart {ihnp4,amdahl,sun}!ptsfa!laticorp!sarah
crash@jc3b21.UUCP (Frank (Crash) Edwards) (10/11/87)
In article <321@laticorp.UUCP>, sarah@laticorp.UUCP (Sarah Groves Hobart) writes: > What is actually being declared is a pointer to an array of pointers. > Remember that the following declarations are equivalent: > > char s[]; > > char *s; > > Most people would tend to call the first declaration a character string, > and the second a character pointer, but they are the same thing. So K&R > are just using slightly different terminology, probably in the interests > of clarity. > > Sarah Groves Hobart > {ihnp4,amdahl,sun}!ptsfa!laticorp!sarah They are the same but they are not the same! Using the strategy above, try the following: ---------- foo.c: char s[] = "This is the character array."; bar.c: extern char *s; ---------- There is a subtle but startling difference between the two; primarily in the storage allocated for each. The declaration in "foo.c" defines storage for the string and sets the array variable s to that address. The extern decl- aration in file "bar.c" indicates that s is an n-byte pointer to the string. This means that to print the string, say, the compiler finds the address of s and the code generated loads a pointer value from it, whereas for a true array the compiler simply uses the value of s at compile time. Perhaps this is obvious to most ;-) but it wasn't to me. My particular run-in with this type of coding was more devious because I declared an array of character strings (similar to argv...) and then referenced them as "ptr to ptr to char". I should note that there won't be a problem if these constructs are used within function calls since the array reference generates an address (for case #1), and the compiler code loads the ptr from address s (for case #2). And so either way a parameter declared as "char *s" would work. This problem only crops up when global declarations are used. Anyway, I hope the above is intelligible. If not, oh well. Frank (Crash) Edwards
stpeters@dawn.steinmetz (Dick St.Peters) (10/12/87)
In article <321@laticorp.UUCP> sarah@laticorp.UUCP (Sarah Groves Hobart) writes: >Remember that the following declarations are equivalent: > >char s[]; > >char *s; Actually, they're not. The difference is like that between a constant and a variable: you can change the value of s (the address it points to) if you declare it as a pointer [variable], but you can't if you declare it as an array [constant]. Consider what "&s" means in the two cases. -- Dick St.Peters GE Corporate R&D, Schenectady, NY stpeters@ge-crd.arpa uunet!steinmetz!stpeters
tim@amdcad.AMD.COM (Tim Olson) (10/13/87)
In article <7608@steinmetz.steinmetz.UUCP> dawn!stpeters@steinmetz.UUCP (Dick St.Peters) writes: | In article <321@laticorp.UUCP> sarah@laticorp.UUCP (Sarah Groves Hobart) writes: | >Remember that the following declarations are equivalent: | > | >char s[]; | > | >char *s; | | Actually, they're not. The difference is like that between a constant | and a variable: you can change the value of s (the address it points | to) if you declare it as a pointer [variable], but you can't if you | declare it as an array [constant]. Consider what "&s" means in the | two cases. Actually, you are both right. There are two places where a declaration of an array with no size (and no initializer) are legal: 1) as a formal parameter, and 2) as an external array declaration, where the array is defined elsewhere. As a formal parameter, char s[] and char *s are equivalent -- the compiler coerces the former into the later. In that case you *can* change s. As an external array declartion, the two are not equivalent. -- Tim Olson Advanced Micro Devices (tim@amdcad.amd.com)
sarah@laticorp.UUCP (Sarah Groves Hobart) (10/13/87)
In article <7608@steinmetz.steinmetz.UUCP>, stpeters@dawn.steinmetz (Dick St.Peters) writes: > In article <321@laticorp.UUCP> sarah@laticorp.UUCP (Sarah Groves Hobart) writes: > >Remember that the following declarations are equivalent: > > > >char s[]; > > > >char *s; > > Actually, they're not. The difference is like that between a constant > and a variable: you can change the value of s (the address it points > to) if you declare it as a pointer [variable], but you can't if you > declare it as an array [constant]. Consider what "&s" means in the > two cases. > > > Right. An array name IS a constant, so something like: ptr = &array_name; is illegal. I was referring to their equivalence as formal parameters in a function definition. A function that has been passed an array name can believe it has either an array or a pointer and work with it accordingly. It is, however, legal to pass a function something of the form &a[0], or even &a[5]. This is useful if you only want to pass part of a larger array. Interested parties are referred to K&R pp. 94-96. Sarah Groves Hobart {ihnp4,amdahl,sun}!ptsfa!laticorp!sarah
stpeters@dawn.steinmetz (Dick St.Peters) (10/15/87)
In article <324@laticorp.UUCP> sarah@laticorp.UUCP (Sarah Groves Hobart) writes: >Right. An array name IS a constant, so something like: > > ptr = &array_name; > >is illegal. I was referring to their equivalence as formal parameters >in a function definition. Ok, but isn't the non-difference in this case obvious to anyone who knows what a "formal parameter" is? As someone who has spent many hours trying to introduce to C people who are basically non-programmers but must do a little programming, is there any way I can get you folks to stop using the term "formal parameter" when "function argument" or "procedure argument" will do as well? I am tired of translating and being asked what an informal parameter is. -- Dick St.Peters GE Corporate R&D, Schenectady, NY stpeters@ge-crd.arpa uunet!steinmetz!stpeters
cameron@elecvax.eecs.unsw.oz (Cameron Simpson) (10/16/87)
In article <18668@amdcad.AMD.COM> tim@amdcad.AMD.COM (Tim Olson) writes: >In article <7608@steinmetz.steinmetz.UUCP> dawn!stpeters@steinmetz.UUCP (Dick St.Peters) writes: >| In article <321@laticorp.UUCP> sarah@laticorp.UUCP (Sarah Groves Hobart) writes: >| >Remember that the following declarations are equivalent: >| >char s[]; >| >char *s; >| Actually, they're not. [ explaination deleted ] >Actually, you are both right. There are two places where a declaration >of an array with no size (and no initializer) are legal: 1) as a formal >parameter, and 2) as an external array declaration, where the array is >defined elsewhere. >As a formal parameter, char s[] and char *s are equivalent -- the >compiler coerces the former into the later. In that case you *can* >change s. As an external array declartion, the two are not equivalent. > -- Tim Olson > Advanced Micro Devices > (tim@amdcad.amd.com) I've been following this for a while. In all this discussion I have not once seen a word which crops up several times in K&R, namely `lvalue'. An lvalue is something which may occur on the left-hand side of an assignment statement. If I say char s[]; /* a character array of unspecified size */ char *t; /* a pointer to a character */ then I may say `t++;' or `t = s;' or `t = &s[2];' and so on. I may not say `s++;' or `s = t;'. This applies whether they are declared as formal parameters or as external array declarations. I often declare functions like fn(a,b) char *a; char b[]; in order to *prevent* myself from changing b during the function. It eliminates some coding errors by making the compiler do some extra checking for me. - Cameron Simpson, Uni of NSW, Australia
chris@mimsy.UUCP (Chris Torek) (10/16/87)
In article <7639@steinmetz.steinmetz.UUCP> stpeters@dawn.steinmetz (Dick St.Peters) writes: >As someone who has spent many hours trying to introduce to C people >who are basically non-programmers but must do a little programming, is >there any way I can get you folks to stop using the term "formal >parameter" when "function argument" or "procedure argument" will do as >well? It is rare that `function argument' will do as well as `formal parameter'. `Function argument' can also mean `actual parameter', and formal-parameter pointer/array conversions are not performed on actual parameters. (Jargon *does* have its uses, and every occupation has its jargon. Perhaps the first thing you should introduce is the jargon.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
guy%gorodish@Sun.COM (Guy Harris) (10/18/87)
> This applies whether they are declared as formal parameters or as > external array declarations. I often declare functions like > fn(a,b) > char *a; > char b[]; > in order to *prevent* myself from changing b during the function. > It eliminates some coding errors by making the compiler do some > extra checking for me. Umm, guess again. K&R says, in 10.1 "External function definitions": ...Also, since a reference to an array in any context (in particular as an actual parameter) is taken to mean a pointer to the first element of the array, declarations of formal parameters declared ``array of ...'' are adjusted to read ``pointer to ...'''. Which means that the compiler will treat the declarations of "a" *and* "b" as declarations of pointers. Furthermore, PCC, at least, works this way, so most PCC-based compilers aren't doing any extra checking for you. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
chris@mimsy.UUCP (Chris Torek) (10/18/87)
(This discussion should have been in comp.lang.c; followups have been directed there.) In article <3802@elecvax.eecs.unsw.oz> cameron@elecvax.eecs.unsw.oz (Cameron Simpson) writes: >... An lvalue is something which may occur on the left-hand side of an >assignment statement. If I say > char s[]; /* a character array of unspecified size */ > char *t; /* a pointer to a character */ >then I may say `t++;' or `t = s;' or `t = &s[2];' and so on. >I may not say `s++;' or `s = t;'. True enough, except . . . . >This applies whether they are declared as formal parameters or as >external array declarations. I often declare functions like > fn(a,b) > char *a; > char b[]; >in order to *prevent* myself from changing b during the function. . . . this does not work in (some? many? most? all?) compilers. PCC is perfectly happy with `b = a' inside the code for `fn'. I am not sure whether the draft has anything to say on the subject. Incidentally, with the addition of `const', ANSI now has the concept of `modifiable lvalues', so that in const int n = 4; `n' is an lvalue, but not a modifiable lvalue. (At least, I think this is how it works---there are odd possibilities like const volatile int *clockaddr = (int *)CLOCK_ADDRESS; that I am still not sure about.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/19/87)
In article <7639@steinmetz.steinmetz.UUCP> stpeters@dawn.UUCP (Dick St.Peters) writes: >In article <324@laticorp.UUCP> sarah@laticorp.UUCP (Sarah Groves Hobart) writes: >>I was referring to their equivalence as formal parameters >>in a function definition. >Ok, but isn't the non-difference in this case obvious to anyone who >knows what a "formal parameter" is? Obviously not; the original question concerned the declaration for the formal parameter `argv', but some people then piped up saying that * and [] were not equivalent, which they in fact are in such usage. >As someone who has spent many hours trying to introduce to C people >who are basically non-programmers but must do a little programming, is >there any way I can get you folks to stop using the term "formal >parameter" when "function argument" or "procedure argument" will do as >well? No, because it is incorrect to call a formal parameter an `argument'. The argument is the value that is actually supplied when the function is invoked, and this has very little to do with the definition of the function itself, for which the formal parameters are quite significant. If you think that naive programmers will be less confused were we to use less precise terminology, well, that is not confirmed in my experience.
stpeters@dawn.steinmetz (Dick St.Peters) (10/26/87)
In article <6585@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >If you think that naive programmers will be less confused were we to >use less precise terminology, well, that is not confirmed in my >experience. It is my experience that people are less confused by terminology they understand. Jargon can turn a generally correct statement into a precise one, but to a naive listener/reader, it can turn the statement into a meaningless one. I would rather be imprecise than incomprehensible. This particular piece of jargon ("formal parameters") is a sore point because I get asked about it so much. However, I obviously chose a poor place to raise the issue, and I'm sorry about that. Not many naive programmers read comp.unix.wizards. -- Dick St.Peters GE Corporate R&D, Schenectady, NY stpeters@ge-crd.arpa uunet!steinmetz!stpeters