[comp.lang.c] Global and Extern Pointers, Arrays

aj3u@agate.cs.virginia.edu (Asim Jalis) (05/23/91)

I just figured out the following bug in my program.  I had a global
array, with some initialized value that I was also declared an extern
pointer in the other files that accessing it.  This turns out to be a
no-no.  The bug went away when I changed the extern definition to an
array also.  

Here is the code:

file.1
	struct x px[1] = { ... };

file.2
	extern *px	/* boinks */
	extern px[]	/* works */

Any ideas as to why this is?

Asim Jalis.

henry@zoo.toronto.edu (Henry Spencer) (05/23/91)

In article <AJ3U.91May22202642@agate.cs.virginia.edu> aj3u@agate.cs.virginia.edu (Asim Jalis) writes:
>I just figured out the following bug in my program.  I had a global
>array, with some initialized value that I was also declared an extern
>pointer in the other files that accessing it...
>Any ideas as to why this is?

Because arrays are not pointers.
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (05/24/91)

In article <AJ3U.91May22202642@agate.cs.virginia.edu> aj3u@agate.cs.virginia.edu (Asim Jalis) writes:
>file.1
>	struct x px[1] = { ... };
>file.2
>	extern *px	/* boinks */
>	extern px[]	/* works */
>Any ideas as to why this is?

Sure, but the question is, why would you think it ought to work the
other way, where there is a clear type mismatch?  The only thing I
can think of is that somehow you have gotten the notion that arrays
and pointers are the same thing; that is false, and you should learn
what the difference is and why under SOME circumstances the two types
"seem" to act the same.  I'm sure this information is widely available,
probably in the FAQ list.

gordon@osiris.cso.uiuc.edu (John Gordon) (05/24/91)

aj3u@agate.cs.virginia.edu (Asim Jalis) writes:

>I just figured out the following bug in my program.  I had a global
>array, with some initialized value that I was also declared an extern
>pointer in the other files that accessing it.  This turns out to be a
>no-no.  The bug went away when I changed the extern definition to an
>array also.  

>Here is the code:

>file.1
>	struct x px[1] = { ... };

>file.2
>	extern *px	/* boinks */
>	extern px[]	/* works */

>Any ideas as to why this is?

	Arrays and pointers are mostly analogous most of the time.  However,
this is one of the things about them that are NOT the same.

John

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (05/24/91)

In <AJ3U.91May22202642@agate.cs.virginia.edu>
aj3u@agate.cs.virginia.edu (Asim Jalis) askes about a bug caused by the
difference between the following:

>	extern *px	/* boinks */
>	extern px[]	/* works */

Asim's question is a VVFAQ (very very frequently asked question).  In
my early C days I asked it often.  Then I wrote an answer.  Here it
is.

Date:    12 Dec 90 03:27:15 GMT
From:    dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi)
Newsgroups: comp.lang.c
Subject: Re: confusion with char *a and char a[NUM]
References: <7656@umd5.umd.edu> <1990Dec6.055844.5333@clear.com>
Sender:  cirrusl!news
Distribution: na
Organization: Cirrus Logic Inc.

Let me give you a different way of understanding the difference between
char *A and char B[NUM].

After you have used malloc to assign NUM characters of storage for A,
both A and B can be used in a very similar way.  In some contexts any
reference to A or B is treated as the use of a pointer.

However, B is not a pointer.  It's just treated like one sometimes.  It
is a SYMBOLIC NAME FOR AN ADDRESS.  (And remember that a pointer is not
an address; it's a way of finding an address.)  In place of B you could
(if the language allowed it) use the absolute value of the address of
the array you call B.  You can pretend that the instant you use B, the
compiler converts it to the address for which B is a symbolic name.

A is not the same thing.  It is a VARIABLE, not an address.  The
variable is at some address, but when you use A, you usually
dereference that variable, and reach some other address.  This is why A
really *is* a pointer variable, while B is merely *treated* like one.

So, what happens when you do something like "A[3] = 7" or "B[3] = 7"?
In the first case, the compiler generates code to look at the CONTENTS
of the variable A, get those contents and add 3 to them, and treat the
result as an address.  B, however, is a symbolic name for an address.
The compiler generates code to directly take that address, add 3 to it,
and get another address.  In both cases, after the address is obtained,
a value of 7 is stored at that address.  (The above description is not
strictly accurate if A or B is on the stack.  For this description,
let's assume they are statically allocated and not in the stack.)

The terms "pointer" and "address" are often erroneously used with the
same meaning.  They are not the same.  An address is a location.  A
pointer is a way of getting to a location.  Think of the pointer as an
arrow pointing somewhere, and an address as the place the arrow is
pointing to.  A, the pointer, is an arrow, and it points to the address
where malloc() gave us memory.  B, the address, doesn't point anywhere
-- it *is* already an address.  A (a pointer) could point to B (an
address).  But B (an address) can never point to A, because B is not a
pointer.
--
Rahul Dhesi <dhesi@cirrus.COM>
UUCP:  oliveb!cirrusl!dhesi

gwyn@smoke.brl.mil (Doug Gwyn) (05/25/91)

In article <3153@cirrusl.UUCP> Rahul Dhesi <dhesi@cirrus.COM> writes:
>However, B is not a pointer.  It's just treated like one sometimes.  It
>is a SYMBOLIC NAME FOR AN ADDRESS.

I really cannot condone looking at array names like that.
The name of an array is just that, the name of an array.
Whether or not it has anything to do with an "address" depends on the context.
For example, in "sizeof B", the array name B has nothing whatever to do with
an address; it represents the entire CONTENT of the array.

throopw@sheol.UUCP (Wayne Throop) (05/27/91)

> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi)
> [...] char *A and char B[NUM]. [...]
> However, B is not a pointer.  It's just treated like one sometimes.  It
> is a SYMBOLIC NAME FOR AN ADDRESS.

This is a bad model for thinking about pointers and arrays, because
it makes things like sizeof anomalous in the model.  It also uses
words in ways incompatible with the way they are used in the standard,
thus perpetuating confusion.

Why not approach it as the orthodox do?

A is a pointer, B is an array.  Arrays are converted to pointer values
when used in expressions where a value is required, which leads the
heterodox to falsely claim that "arrays and pointers are the same thing
in C". 

What's so complicated about this that it need come up so often?
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw

xwang@gmuvax2.gmu.edu (Xiang-Min Wang) (05/31/91)

In article <AJ3U.91May22202642@agate.cs.virginia.edu> aj3u@agate.cs.virginia.edu (Asim Jalis) writes:
>I just figured out the following bug in my program.  I had a global
>array, with some initialized value that I was also declared an extern
>pointer in the other files that accessing it.  This turns out to be a
>no-no.  The bug went away when I changed the extern definition to an
>array also.  
>
>Here is the code:
>
>file.1
>	struct x px[1] = { ... };
>
>file.2
>	extern *px	/* boinks */
>	extern px[]	/* works */
>
>Any ideas as to why this is?
>
>Asim Jalis.

Hi, Asim. in your file 'file.2', you should declare px as  

         extern struct x px[1]

telling the compiter that px[1] is of type 'struct x' but do not need bother
allocating memory for it. 

as to why your second solution works, well, there are a lot of luck out there
in c programming. so good luck.

xwang

sundar_b@apollo.hp.com (Sundar Balasubramanian) (06/15/91)

This is a test\
please ignore