scope and linkage

R

rick

I'm working on a disassembler for a school project.

Things work but I get compiler warnings as follows:
cc -W -Wall -pedantic -ansi main.c
defs.h:44: warning: 'blah' defined but not used

blah is a static variable, so visible only to defs.h (and files that
include defs.h?).
Without the static qualifier the compiler bails with
main.o: multiple definition of 'blah'
main.o: first defined here
collect2: ld returned 1 exit status
make: *** [all] Error 1


The warnings are invisible w/o the -Wall compile flag.
I just want to know if there is a way to declare 'blah' that will avoid
the warning.

here is the program structure:

FILE: main.c
#include dis.h
/* only calls one function in dis.h */

FILE: dis.h
#include defs.h

FILE: dis.c
#include dis.h
/* uses almost everything in defs.h */

FILE: defs.h
static const char* blah[ SIZE ] = { ... };


Like I said, I'm just looking to compile cleanly with the CFLAGS above.
thanks for any help!
 
J

Jack Klein

I'm working on a disassembler for a school project.

Things work but I get compiler warnings as follows:
cc -W -Wall -pedantic -ansi main.c
defs.h:44: warning: 'blah' defined but not used

blah is a static variable, so visible only to defs.h (and files that
include defs.h?).

An included file like "defs.h" has no visibility at all. Translation
units have things with visibility in them. A translation unit is
roughly a compiled source file plus everything it includes.
Without the static qualifier the compiler bails with
main.o: multiple definition of 'blah'
main.o: first defined here
collect2: ld returned 1 exit status
make: *** [all] Error 1


The warnings are invisible w/o the -Wall compile flag.
I just want to know if there is a way to declare 'blah' that will avoid
the warning.

Your problem is bigger than the warning. The warning is telling you
that you are creating, not just declaring, an array in main.c that is
not referenced by any code in main.c. It's address is not even taken,
so it is completely unused by your program. The contents of defs.h is
a declaration, but is it also a definition that creates and
initializes blah.
here is the program structure:

FILE: main.c
#include dis.h
/* only calls one function in dis.h */

FILE: dis.h
#include defs.h

FILE: dis.c
#include dis.h
/* uses almost everything in defs.h */

FILE: defs.h
static const char* blah[ SIZE ] = { ... };


Like I said, I'm just looking to compile cleanly with the CFLAGS above.
thanks for any help!

The problem is that you are defining data in a header, which is
incorrect. Your program ends up with two identical copies of the blah
array, perhaps even more than two if any other source files include
defs.h directly or indirectly. If you have a hundred C source files
in your program, and each of them includes defs.h directly or
indirectly, you will end up with one hundred identical copies of this
array.

The solution is simple, don't define data objects in an include file.
If only dis.c needs to access this data, put it in dis.c.

If more than one source file needs to access it, instead of putting it
in a header that causes each source file to create its own copy, do
this instead.

Create a header file called blah.h, it should contain:

extern const char * const blah [SIZE];

....assuming that you never modify the pointers in the array.

Include this in all source files that need to reference these strings.
Then in exactly one source file, or in a new source file named blah.c,
put:

const char * const blah [SIZE] = { /* initializers */ };

Remember, defining data objects in include files is almost always a
bad idea.
 
F

Fred Kleinschmidt

rick said:
I'm working on a disassembler for a school project.

Things work but I get compiler warnings as follows:
cc -W -Wall -pedantic -ansi main.c
defs.h:44: warning: 'blah' defined but not used

blah is a static variable, so visible only to defs.h (and files that
include defs.h?).
Without the static qualifier the compiler bails with
main.o: multiple definition of 'blah'
main.o: first defined here
collect2: ld returned 1 exit status
make: *** [all] Error 1


The warnings are invisible w/o the -Wall compile flag.
I just want to know if there is a way to declare 'blah' that will avoid
the warning.

here is the program structure:

FILE: main.c
#include dis.h
/* only calls one function in dis.h */

FILE: dis.h
#include defs.h

FILE: dis.c
#include dis.h
/* uses almost everything in defs.h */

FILE: defs.h
static const char* blah[ SIZE ] = { ... };


Like I said, I'm just looking to compile cleanly with the CFLAGS above.
thanks for any help!

the compiler is telling you that you have defined a variable called blah,
but that variable is never referenced in your program. To compile "cleanly",
you have two choices:
1) remove the definition of blah from defs.h,
or
2) Use blah somewhere in your program
 
R

rick

Well that explains a lot!

Using the blah.h and blah.c idea,
the program now builds without incident.

Finally a good explanation of scope across multiple files!
Thanks!
 
C

CBFalconer

rick said:
.... snip ...

here is the program structure:

FILE: main.c
#include dis.h
/* only calls one function in dis.h */

FILE: dis.h
#include defs.h

FILE: dis.c
#include dis.h
/* uses almost everything in defs.h */

FILE: defs.h
static const char* blah[ SIZE ] = { ... };

Like I said, I'm just looking to compile cleanly with the CFLAGS
above. thanks for any help!

Several things. First, why does dis.h include defs.h in the first
place? The only purpose of dis.h is to expose things in dis.c that
need to be accessed from other modules, the only one of which I see
is main.c. So the only thing needed in dis.h is that function
called from main.

Second, why does defs.h define any data storage in the first
place? That is generally a no-no. The storage is only used in
dis.c, so simply define it within difs.c in the first place.
Apparently this applies to everything in defs.h anyhow, so why does
that file even exist?

Since only one function within difs.c is ever called from outside,
every other function in that module should be classified as
'static'. Similarly for any data (hopefully none) that is declared
in file scope.

Restrict access and scope as far as possible, and you should have
no problems.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
J

Jack Klein

On 31 Mar 2006 11:49:33 -0800, "rick" <[email protected]
wrot
in comp.lang.c
I'm working on a disassembler for a school project

Things work but I get compiler warnings as follows
cc -W -Wall -pedantic -ansi main.
defs.h:44: warning: 'blah' defined but not use

blah is a static variable, so visible only to defs.h (and files tha
include defs.h?)
An included file like "defs.h" has no visibility at all. Translatio
units have things with visibility in them. A translation unit i
roughly a compiled source file plus everything it includes
Without the static qualifier the compiler bails wit
main.o: multiple definition of 'blah
main.o: first defined her
collect2: ld returned 1 exit statu
make: *** [all] Error


The warnings are invisible w/o the -Wall compile flag
I just want to know if there is a way to declare 'blah' that wil avoi
the warning
Your problem is bigger than the warning. The warning is telling yo
that you are creating, not just declaring, an array in main.c that i
not referenced by any code in main.c. It's address is not even taken
so it is completely unused by your program. The contents of defs.h i
a declaration, but is it also a definition that creates an
initializes blah
here is the program structure

FILE: main.
#include dis.
/* only calls one function in dis.h *

FILE: dis.
#include defs.

FILE: dis.
#include dis.
/* uses almost everything in defs.h *

FILE: defs.
static const char* blah[ SIZE ] = { ... }


Like I said, I'm just looking to compile cleanly with the CFLAG above
thanks for any help
The problem is that you are defining data in a header, which i
incorrect. Your program ends up with two identical copies of the bla
array, perhaps even more than two if any other source files includ
defs.h directly or indirectly. If you have a hundred C source file
in your program, and each of them includes defs.h directly o
indirectly, you will end up with one hundred identical copies of thi
array

The solution is simple, don't define data objects in an include file
If only dis.c needs to access this data, put it in dis.c

If more than one source file needs to access it, instead of putting i
in a header that causes each source file to create its own copy, d
this instead

Create a header file called blah.h, it should contain

extern const char * const blah [SIZE]

....assuming that you never modify the pointers in the array

Include this in all source files that need to reference these strings
Then in exactly one source file, or in a new source file named blah.c
put

const char * const blah [SIZE] = { /* initializers */ }

Remember, defining data objects in include files is almost always
bad idea

--
Jack Klei
Home: http://JK-Technology.Co
FAQs fo
comp.lang.c http://c-faq.com
comp.lang.c++ http://www.parashift.com/c++-faq-lite
alt.comp.lang.learn.c-c+
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.htm
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top