external linking

B

bill

I'm not sure if this belongs in comp.lang.c or in a compiler group, but
I'm experiencing some confusion. Consider:

[tmp]$ cat a.c
const char t[]={0xef, 0xbe, 0xad, 0xde};
const char *a=t;
int bar(void);

int
main()
{
return bar();
}
[tmp]$ cat b.c
extern const char *t;

int
bar(void)
{
return t[0];
}
[tmp]$ gcc -c b.c
[tmp]$ gcc a.c b.o
[tmp]$ ./a.out
Segmentation fault

Looking at the running process through gdb, we see that the segfault
occurs because the attempt to reference t[0] in bar attempts to
dereference the address 0xdeadbeef, which is an illegal address. If
we replace 't' with 'a' in baz, everything works fine. I'm trying to
understand the proper way to initialize constant arrays that are used
accross multiple files (don't want to define them as static as I end up
with multiple copies in the a.out, which I suppose is compiler
dependent and gcc is not doing the right thing with -fmerge-constants
(well, I called it as -Os, and my reading of the man page is that this
implies -fmerge-constants)).

Any insight appreciated.
 
T

Tim Rentsch

bill said:
I'm not sure if this belongs in comp.lang.c or in a compiler group, but
I'm experiencing some confusion. Consider:

[tmp]$ cat a.c
const char t[]={0xef, 0xbe, 0xad, 0xde};
const char *a=t;
int bar(void);

int
main()
{
return bar();
}
[tmp]$ cat b.c
extern const char *t;

int
bar(void)
{
return t[0];
}
[tmp]$ gcc -c b.c
[tmp]$ gcc a.c b.o
[tmp]$ ./a.out
Segmentation fault

Looking at the running process through gdb, we see that the segfault
occurs because the attempt to reference t[0] in bar attempts to
dereference the address 0xdeadbeef, which is an illegal address. If
we replace 't' with 'a' in baz, everything works fine. I'm trying to
understand the proper way to initialize constant arrays that are used
accross multiple files (don't want to define them as static as I end up
with multiple copies in the a.out, which I suppose is compiler
dependent and gcc is not doing the right thing with -fmerge-constants
(well, I called it as -Os, and my reading of the man page is that this
implies -fmerge-constants)).

Any insight appreciated.

The reason your program isn't working is that, in a.c, you
declare/define 't' with

const char t[]=...;

which is to say t is declared to be an array, and then in
b.c you declare 't' with

extern const char *t;

which is to say t is declared to be a pointer. The mismatch
of types -- array in one case, pointer in another -- causes
inappropriate code to be generated that accesses the array
't' as though it were a pointer. The result is what you
see.

To fix the problem, declare 't' in b.c as an array rather
than a pointer:

extern const char t[];

If you don't understand the difference between arrays and
pointers, then you need to do some more reading; but I'm
guessing you understand enough to know that they are
different. The declaration 'char t[];' declares an array,
and the declaration 'char *t;' declares a pointer. These
types are not "compatible", to use the technical term of the
Standard, and when used together in different compilation
units this way will usually cause problems.

To add to the confusion, when a variable is a function
parameter, a declaration like

int foo( char name[] ){ ... }

says that the parameter 'name' is a *pointer* rather than an
array: an array-like declaration is changed into a pointer
type in a function parameter context. But that rule applies
only for function parameters, not to variables declared at
the top level (or anywhere besides parameters, for that
matter).
 
M

Martin Ambuhl

bill said:
I'm not sure if this belongs in comp.lang.c or in a compiler group, but
I'm experiencing some confusion. Consider:

[tmp]$ cat a.c
const char t[]={0xef, 0xbe, 0xad, 0xde}; [...]
[tmp]$ cat b.c
extern const char *t;

const char t[] = { /* whatever */ }; /* is an array */
const chat *t; /* is a pointer */

Repeat the mantra: "An array is not a pointer."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,459
Latest member
Vida00R129

Latest Threads

Top