Difference between "char *arr" and "char arr[]" 
Author Message
 Difference between "char *arr" and "char arr[]"

In file "a.c", I declare:
char targ[128];

In file "b.c" I do:
extern char *targ;

Result: I got massive errors. When I source debugged it, it told me
that the char pointer "targ" was 0x000000.

By chance, I tried redeclaring it as "extern char targ[]" and
the problem was fixed.

Now, I always thought that "targ[]" and "char *targ" were equivalent.
I have several places in my program where I use those two notations
interchangeably, and this was the first time I've ever had a problem
with it.

Could a C wizard explain to me what I'm doing wrong and what the
correct practice is so I don't run into these horrible bugs again?

Thanks in advance.

- f



Wed, 10 Mar 1993 11:23:35 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:

>In file "a.c", I declare:
>char targ[128];

>In file "b.c" I do:
>extern char *targ;

>Result: I got massive errors. When I source debugged it, it told me
>that the char pointer "targ" was 0x000000.

>By chance, I tried redeclaring it as "extern char targ[]" and
>the problem was fixed.

>Now, I always thought that "targ[]" and "char *targ" were equivalent.
>I have several places in my program where I use those two notations
>interchangeably, and this was the first time I've ever had a problem
>with it.

>Could a C wizard explain to me what I'm doing wrong and what the
>correct practice is so I don't run into these horrible bugs again?

No wizard, but here it is. The compiler will allow you to mix the array/pointer
notation and will get it right. To do this it needs to know what the reality
is. In other words, once you declare the array/pointer correctly, you cac then
access it either way. The generates assembler to access a pointer is not the
same as accessing an array. C has some 'promotion rules' which define the
behaviour of the expression array[index] and pointer[index]: the name of
an array is promoted to 'a pointer to the first element'. Anyway, the short
answer is YOU MUST DECLARE IT CORRECTLY, CANNOT MIX POINTER/ARRAY IN THE
DECLARATION.
BTW, in function arguments there is another promotion rule which allows you
to mix pointer/array here.

Any clearer now ? hope so.>

Quote:
>Thanks in advance.

>- f

--
Regards
        Eyal


Wed, 10 Mar 1993 17:30:28 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:
>Now, I always thought that "targ[]" and "char *targ" were equivalent.
>I have several places in my program where I use those two notations
>interchangeably, and this was the first time I've ever had a problem
>with it.

They are equivalent (with respect to referencing data) for just about all
cases EXCEPT for global variables.

The reason that they are equivalent for function calls is that the array is
acutally converted to (and passed as) a pointer.  

For global variables "targ" will represent a location in memory assigned
by the linker.  Any mention of the variable "targ" will be replaced by
an absolute memory location by the linker.  The contents of this memory
location will differ depending upon the declaration of targ.

        If it is declared as "char * targ;",
                the compiler will expect a character pointer at this location
        If it is declared as "char targ[xx];"
                the compiler will expect a character arrry starting at this
                location

Quote:
>correct practice is so I don't run into these horrible bugs again?

The correct practice is that global declarations and references much
match exactly (except initializations of course).

--
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170



Wed, 10 Mar 1993 21:03:45 GMT  
 Difference between "char *arr" and "char arr[]"
In case nobody else has mentioned it (I came in late on this one), there
is a difference between *x and x[] besides allocation and semantics for
globals: sizeof().  A lot of times I've been tempted to write

        static char *message = "hello";
        /* ... */
        write(fd,message,sizeof(message));

within a routine.  Obviously this won't work, but

        static char message[] = "hello";

will.  It's amazing how easy it is to forget this little detail and how
many times I've seen it done.  Usuaully it's much more insidious than
this example.
--


      Nothing was ever achieved by accepting reality



Thu, 11 Mar 1993 02:58:44 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:

> Now, I always thought that "targ[]" and "char *targ" were equivalent.

As an aside, I took a survey a while back about this.  It turns out
that the reason for this frequent misconception is (essentially)
poor teaching and poor reference materials.  Essentially teachers
TEACH people this, sometimes inadvertantly.

My main suggestion to Frank Kuan is to read the "Frequently Asked
Questions" posting when it comes around again.  You will find the
answer to the [] vs * question, along with a slew of other things
that teachers (apparently) often mis-teach students.

Quote:

> They are equivalent (with respect to referencing data) for just about all
> cases EXCEPT for global variables.

And automatic variables.  And objects in the malloc/free heap.  And
variables with static visibility/persistence.

I think that Conor may be taking "equivalent" to mean that the two
objects can appear in lexically identical references.  Which is correct.
But the semantics which apply to the two cases are distinct.

The fact is, there is only ONE place where the two are semantically
equivalent, and that is as definitions of formal parameters.  Again, see
the FAQ for details, but code generated for subscripting, "sizeof"
results, and in essence *everything* is different for these two
declarations, with only the one exception.

So, while Conor is technically correct, I think it is much more
important to emphasize the differences here, rather than the similarities.
The similarities are superficial, and the differences important,
fundamental, and often overlooked.
--



Thu, 11 Mar 1993 06:27:51 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:

>    static char message[] = "hello";
>    /* ... */
>    write(fd,message,sizeof(message));

Note that (sizeof(message)) is 6... the suggested "write" will
solve the question on that other thread... how to write a NUL to a file.

( Also note that the form as it appears in the Subject: line has
  been known to break pcc-based compilers if I remember right... they
  were promoting "foobar" to a pointer "too soon". Getting Jeff's verseion
  wrong seems much, much rarer. )
--



Thu, 11 Mar 1993 06:28:02 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:
>    global unsigned long avail[A,B,C];

and as several people have pointed out already, that's not how you declare
a multi-dimensional array in C.  *blush*

What can I say?  I'd just resurfaced after a lot of fortran programming
involving arrays, though...  Still, I must have been temporarily blind.

Thanks to all who took the time to point this out to me!  :-)

-tih
--
Tom Ivar Helbekkmo, NHH, Bergen, Norway.  Telephone: +47-5-959205



Thu, 11 Mar 1993 20:07:03 GMT  
 Difference between "char *arr" and "char arr[]"
Let me venture a concise explanation to this difference:

        extern char *arr        declares an object, containing a
                                pointer to a character

        extern char arr[]       declares a constant pointer to a
                                character

Hope this helps.
--
[Erik Naggum]           Naggum Software; Gaustadalleen 21; 0371 OSLO; NORWAY

  therefore I post.     +47-295-8622, +47-256-7822, (fax) +47-260-4427



Fri, 12 Mar 1993 05:11:12 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:

>Let me venture a concise explanation to this difference:

>    extern char *arr        declares an object, containing a
>                            pointer to a character

>    extern char arr[]       declares a constant pointer to a
>                            character

Concise, yes; correct, no.  Both declare objects; the latter declares
an object that is an array.  It IS an array; it is NOT a pointer.  The
confusion occurs because objects that are arrays are *converted into*
VALUES that are pointers, whenever the value is called for.

In other words, if `x' is an array, one might try to describe the
`value' of x as the values of all elements of x.  (Mathematically, `the
value of x' would be `the set of all values x[i] such that x[i]
exists.')  If `x' is a large array, that would be an awful lot of
values.  Most computers can only work on one or two or maybe a dozen
or a hundred values at a time, and x could easily contain several
thousand values.  So the C language does not provide a way to talk
about this kind of `value of x'.

Instead, when you ask for the `value' of x (where x is some array),
the language gives you a convenient place to start if you wanted to
go about finding all of the (possibly many thousands of) values x[i].
Indeed, it tells you where the very first such value is stored.  In
other words, it changes an

        <object, array 8000 of int, x>

into a

        <value, pointer to int, &x[0]>

and you can then go about fetching all 8000 values yourself, using
this pointer.

Since it changes the <object, array N of T> into a <value, pointer to T>,
the result is not something you can change---you cannot, after the fact,
change the place the system decided to store the array, at least not in
the C language proper (assembly language hacking is another matter)---and
this leads people to (incorrectly) decide that an array `is' a constant.
It is nothing of the sort: an array IS an array.  It is not something you
can change, but it is also not a constant, as the (nonportable) program

        #include <stdio.h>
        void f(v) int v; {
                int arr[1000];
                printf("%lx\n", (long)arr);
                if (v) f(0);
        }
        int main() { f(1); return 0; }

will demonstrate on those systems that do not remove the tail recursion.
(You will get two different numbers.)

(N.B.: By switching from one meaning to another, you *can* say that an
array `is a constant'.  In C, as in many languages, `constant' is a
language concept meaning `a value that never changes'.  But the
location of an array *can* change, at least if that array is
automatic.  You, as a programmer, may not change it; the system can.
If you decide that you want the word `constant' to mean `I, as a
programmer, may not change this', then of course the location is *that*
sort of `constant'.  But you will confuse everyone else---as I probably
just did with this whole aside.)
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)



Fri, 12 Mar 1993 14:03:02 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:

> Let me venture a concise explanation to this difference:

>    extern char *arr        declares an object, containing a
>                            pointer to a character

>    extern char arr[]       declares a constant pointer to a
>                            character


Quote:
> Concise, yes; correct, no.  Both declare objects; the latter declares
> an object that is an array.  It IS an array; it is NOT a pointer.  The
> confusion occurs because objects that are arrays are *converted into*
> VALUES that are pointers, whenever the value is called for.

Rather, "char arr[14]" declares an array, but "extern char arr[]" only
declares that "arr" is some constant pointer the value of which is to
be resolved by the linker.  "char *arr" declares an object, and
"extern char *arr" declares that "arr" is some object the address of
which is to be resolved by the linker.

I think you overlooked the "extern" up there.  I follow your arguments
for locally declared objects down to the finest details.

Strictly speaking, I have to correct my own explanation: Neither
declares objects, but instead object names with types and values of
that type to be resolved by the linker (or later, anyhow).

I hope this gets a "concise, no; correct, yes" response, at least.

--
[Erik Naggum]           Naggum Software; Gaustadalleen 21; 0371 OSLO; NORWAY

  therefore I post.     +47-295-8622, +47-256-7822, (fax) +47-260-4427



Sat, 13 Mar 1993 07:00:04 GMT  
 Difference between "char *arr" and "char arr[]"

Quote:

>Rather, "char arr[14]" declares an array, but "extern char arr[]" only
>declares that "arr" is some constant pointer the value of which is to
>be resolved by the linker.

I disagree.  Both are *declarations*; the one without "extern" happens to also
serve as a *definition*.  So I would say that "char arr[14]" declares an array
and (being a definition) also causes storage to be allocated for it (probably
by a linker), while "extern char arr[]" declares an array and causes the name
"arr" to be associated with the same storage that was allocated under that
name in some other compilation unit.

There are no pointers (in the C sense) involved here, at least not until such
time as the name "arr" is used in an rvalue context.




Sat, 13 Mar 1993 11:36:44 GMT  
 Difference between "char *arr" and "char arr[]"

explained why 'extern char *arr' and 'extern char arr[]' isn't the same thing.

I admire you, Chris, for having so much patience.  The answer I had expected was
RTFM or RTFFAQ.
--

                Path:           uunet!mcsun!orcenl!bengsig
                From IBM:       auschs!ibmaus!cs.utexas.edu!uunet!oracle!bengsig



Sat, 13 Mar 1993 16:16:09 GMT  
 Difference between "char *arr" and "char arr[]"
Following the discussion, I feel that two issues are beeing mixed:
1 - an object is either an array OR a pointer with no ambiguity.
2 - a reference to an object can mix array/pointer notation.

If an object is declared/defined so as to lead the compiler to see it as an
array then all references will follow this notion, same with pointer.
So: a[4] can be used to refer to 'a' (regardless if 'a' is arr/point) and the
appropriate code will be emitted depending on THE TYPE of a. '*(a+4)' will do
the same. The C syntax/semantics defines this clearly.
--
Regards
        Eyal



Sun, 14 Mar 1993 06:30:20 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. difference between "char*" and "const char*"

2. char foo[]=""; vs char* foo="";

3. char a[] = "abc"; char* a = "abc";

4. difference between 'char *arr' and 'char arr []'

5. decode/unescape "%uxxxx" char in VC++

6. char a[] = ("x");

7. Any != between (char) NULL and ""

8. is this allowed char *name = "bryan"

9. Delete "/" from char pointer

10. What is "unsigned char data[0];"

11. Initialize a char* with "a string"???

12. How do YOU pronounce "char"

 

 
Powered by phpBB® Forum Software