kunkee@ficc.uu.net (randy kunkee XNX MGR) (10/18/89)
Forget that you probably wouldn't want to do the following and
consider the declaration:
char (*foo)[];
This declares "foo" to be a pointer to an array of characters.
My question is, how can you get an assignment to "foo" without
the C compiler complaining about different levels of indirection
(ie. make "foo" point to real storage) without using a typecast?
For example:
main()
{
char (*foo)[];
char bar[20];
foo = bar;
}
Does not work (well, it works, but the compiler complains).
Is my C compiler broken?
To put it another way, is there a declaration of "bar" that will
make the above assignment compile silently, and which allocates
storage for characters?
--
Randy Kunkee
Ferranti International Controls Corporation
12808 W. Airport Blvd. Sugar Land, TX 77478
UUCP: uunet!ficc!kunkee ph: (713) 274-5132
chris@mimsy.umd.edu (Chris Torek) (10/18/89)
`char (*)[]' is an evil, nefarious type which will suck you into a pit of despair. (Fortunately, a fierce green snake bars the way.) In article <6569@ficc.uu.net> kunkee@ficc.uu.net (randy kunkee XNX MGR) writes: >Forget that you probably wouldn't want to do the following and >consider the declaration: > > char (*foo)[]; > >This declares "foo" to be a pointer to an array of characters. More precisely, it declares foo as a pointer to array of unknown size of characters. Foo can then point to zero or more such arrays. The problem is that if foo points to two such arrays, there is no possible way to find where the second such array begins. (The first one begins where foo points, but only because for all x \elem possible-sizes, 0*x gives 0.) >My question is, how can you get an assignment to "foo" without >the C compiler complaining about different levels of indirection >(ie. make "foo" point to real storage) without using a typecast? First you need an array of unknown size. Then simply take its address. The *only* correct way to declare an array of unknown size is as an `extern': extern char bar[]; f() { char (*foo)[]; foo = &bar; } >For example: > >main() >{ > char (*foo)[]; > char bar[20]; > > foo = bar; >} Here `bar' has type `array 20 of char'; in an rvalue context, this changes to type `pointer to char', so a correct version of main() would be int main() { char *foo; char bar[20]; foo = bar; return (0); } In ANSI C (when and if it ever appears), `&bar' will produce a value with type `pointer to array 20 of char', so a second correct version of main() would be main() { char (*foo)[20]; char bar[20]; foo = &bar; exit(0); } (There is no particular significance to the change from `return 0' to `exit 0'.) -- `They were supposed to be green.' In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
kremer@cs.odu.edu (Lloyd Kremer) (10/18/89)
In article <6569@ficc.uu.net> kunkee@ficc.uu.net (randy kunkee XNX MGR) writes: >consider the declaration: > > char (*foo)[]; > >main() >{ > char (*foo)[]; > char bar[20]; > > foo = bar; >} > >Is my C compiler broken? No, your C is broken. :-) In this usage char (*foo)[]; is equivalent to char (*foo)[0]; i.e. a pointer to an array of zero characters -- a pointer to a zero-sized object. Zero-sized objects do not really exist in C, and trying to use them will put you on thin ice. Incrementing a pointer to a zero-sized object leaves it pointing to the same place (assuming the compiler recognizes it at all), so it is not a very useful pointer. Another problem is that you need a fairly recent (pseudo-ANSI) compiler to take the address of an array in the way you want. Older compilers will complain "warning: & operator on array or function: ignored", and give you a pointer to the first element of the array instead of to the array as a whole. Since the start of the array is coincident with the start of its first element, this behavior can be circumvented using a cast. Try the following: char (*foo)[20]; /* pointer to an array of 20 characters */ char bar[20]; /* array of 20 characters */ #ifdef __STDC__ foo = &bar; #else foo = (char (*)[20])bar; #endif -- Lloyd Kremer ...!uunet!xanth!kremer Have terminal...will hack!
rowe@cme.nist.gov (Walter Rowe) (10/18/89)
>>>> On 17 Oct 89 22:37:59 GMT, kunkee@ficc.uu.net (randy kunkee XNX MGR) said:
kunkee> main()
kunkee> {
kunkee> char (*foo)[];
kunkee> char bar[20];
kunkee>
kunkee> foo = bar;
kunkee> }
(1) `bar' is an array of characters
(2) `foo' is a pointer to an array of characters, meaning that it's
supposed to hold the array's address. So, `foo' should hold the
address of `bar'.
(3) The value of `bar' is the address of the first character in the
array. The value of `&bar' is the address of the array `bar'.
The proper assignment, as you already know from other postings, is;
foo = &bar;
Now `foo' contains the address of the array `bar'.
The compiler was right to complain about this since you weren't using
`foo' in the manner that you declared it. Others made that point
clear, however, no one explained the reason why. This is not a flame,
just trying to help you understand how things are interpreted.
Walter
--
This is just my opinion ...
gwyn@smoke.BRL.MIL (Doug Gwyn) (10/19/89)
In article <6569@ficc.uu.net> kunkee@ficc.uu.net (randy kunkee XNX MGR) writes: > char (*foo)[]; > char bar[20]; > foo = bar; >Does not work (well, it works, but the compiler complains). >Is my C compiler broken? No. There are (at least) three problems in this code: (1) bar is the same in the assignment expression as &bar[0], i.e. a char*, which is not compatible with foo. (2) foo has an incomplete type -- it would be impossible for the compiler to generate code to perform pointer arithmetic involving foo, because the size of the object to which foo points has not been specified. >To put it another way, is there a declaration of "bar" that will >make the above assignment compile silently, and which allocates >storage for characters? (3) there are five ways to allocate storage in C: (a) string literals (b) static variables (c) auto variables (d) function arguments (e) invocation of malloc()/realloc()/calloc() execution of an assignment expression is not a way to allocate storage.