C Coding Question
Chris Torek
chris at umcp-cs.UUCP
Sat Aug 16 10:58:44 AEST 1986
In article <138 at darth.UUCP> gary at darth.UUCP (Gary Wisniewski) writes:
>As far as your question about "char *help[]" and "char **help": the two
>forms are IDENTICAL to virtually every C compiler (that's worth its
>salt). Arrays in C are merely special cases of pointers. In other
>words, both forms are correct.
NO!
Ai! This has been asserted far too often. Arrays and pointers are
not at all the same thing in C!
>Section 5.3 of K&R explain this more fully.
Indeed it does, and I suggest you read it rather more carefully.
The correspondence between indexing and pointer arithmetic is
evidently very close. ... The effect is that an array name *is*
a pointer expression. (p. 94)
This does not say that arrays and pointers are *the same*.
There is one difference between an array name and a pointer
that must be kept in mind.
Aha! See p. 94 for that difference.
As formal parameters in a function defintion,
char s[];
and
char *s;
are exactly equivalent.... (p. 95)
Here they *are* the same---but note the qualifier: `As formal
parameters'. In the (unquoted) original example, the array was a
global variable.
There is one other thing which, I guess, adds to this confusion.
Both of the following are legal global declarations in C:
char msg0[] = "Hello, world";
char *msg1 = "Hello, world";
Given both declarations,
printf("%s\n", msg0);
and
printf("%s\n", msg1);
produce the same output. Yet msg0 and msg1 are not the same:
printf("%d %d\n", sizeof (msg0), sizeof (msg1));
prints
13 4
on a Vax; for msg0 is an array, and msg1 is a pointer. The code
generated for the two declarations is different:
/* edited assembly output from ccom */
.data # Switch to data segment.
.globl _msg0 # The array ...
_msg0: .asciz "Hello, world" # and here it is.
.data 2 # Switch to alternate data segment.
L12: .asciz "Hello, world" # The object to which msg1 will point.
.data # Back to regular data segment.
.globl _msg1 # The pointer ...
_msg1: .long L12 # which points to the object.
String constants comprise two special cases in the compiler. The
first case is when the constant appears anywhere *except* as an
initialiser for a `char' array. Here the compiler uses the alternate
data segment to suddenly `create' a new array, initialised to the
string text; it then generates a pointer to that array. In the
second case the string constant is generated in the primary data
segment, and `is' the array being initialised: the constant is
`unwrapped' into an aggregate initialisation.
The second case is actually the more `conventional' of the two;
other aggregates cannot be created at run time:
int a[] = { 0, 1, 2, 3 };
is legal only outside functions. What seems surprising to some is
that the same is true of
char s[] = "foo";
because, unwrapped, this is equivalent to
char s[] = { 'f', 'o', 'o', '\0' };
---even though
char *s = "foo";
is legal anywhere a declaration is legal.
Ah, if only C had aggregate initialisers!
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP: seismo!umcp-cs!chris
CSNet: chris at umcp-cs ARPA: chris at mimsy.umd.edu
More information about the Comp.lang.c
mailing list