extern char *foo vs. extern char foo[]

Paul Nulsen pejn at wolfen.cc.uow.oz
Thu May 31 10:01:02 AEST 1990


In article <1990May30.001219.23564 at uunet!unhd> rg at unhd.unh.edu.UUCP (Roger Gonzalez ) writes:
>According to K&R, there should be no difference between the two extern
>defs in my subject header. ... Here's a
>more detailed example of what I mean:
>
>FILE #1:
>
>     char hello[100];
>     main()
>     {
>         strcpy(hello, "Hello, world.\n");
>         printf("In main(), hello is at %06X\n", hello);
>         foo();
>     }
>
>FILE #2:
>
>     extern char *hello;
>     foo()
>     {
>         printf("In foo(), hello is at %06X\n", hello);
>     }
>
>... I stopped the output at the assembler stage, and
>looked at the .s files for file #2 (using the first method of correction,
>namely declaring extern char hello[]), did a diff, and guess what I found?
>
>>
>mov hello, (sp%)              I know, I know. This isn't *quite* what I
><                             found, but I'm typing it from memory, and its
>mov &hello, (sp%)             close enough for government work.
>
>Aha!  Zees eez very wrong!

The declaration:

	char *hello;

tells the compiler to reserve storage for a one pointer to char. It also
announces that that (global) storage space will be referred to by the name
hello. The declaration:

	extern char *hello;

announces that this has been done somewhere else your program.

The statement:

	char hello[100];

tells the compiler to reserve storage for 100 chars and that this storage is
to be referred to by the name hello. If you inspect the assembler output you
will see that this is indeed how it has interpreted your program. The two
are not equivalent.

The confusion over the difference between char * and char [] is very common.
I believe that it is due to the way that C handles the passing of array
arguments to functions. As rule C passes arguments by value, but it passes
an array argument by reference. This means that passing a char [] to a
function results in the creation of a char * on the stack. As a result,
the programmer is permitted to refer to passed array as either char * or
char [], and the two types of reference are treated in much the same way
within the function.

Another anomaly that we get from this is illustrated by the fragment:

char *pointer_array[] = {"One", "Two", "Three"};
char two_d_array[3][10];

main ()
{
	int i,j;
	for (i = 0; i < 3; i++) {
		strcpy (two_d_array[i], pointer_array[i]);
	}

/* Now (with i,j in bounds) pointer_array[i][j] == two_d_array[i][j] */
/* but these two references are quite different and generate different */
/* code */

	...
}



More information about the Comp.lang.c mailing list