john@ntvax.UUCP (05/16/88)
I am using Turboc 1.5 and am having problems linking files. I am writing a large application (over 64k) and am having trouble breaking up the file. The question is this, when I #include stdio, stdlib etc in multiple source modules the compiler and linker have no problems, however, this is not the case when i #include my own header files. The compile goes ok but the linker gives me the following error - "variable name here" is duplicated in module "source module name here" . This only occurs for my specfic header files not the system (stdio, etc). What can I do to get around this problem. Using extern may help but the header file is very large. Thanks john convex!ntvax!john
swarbric@tramp.Colorado.EDU (Frank Swarbrick) (05/18/88)
In article <28400001@ntvax> john@ntvax.UUCP writes:
:
:I am using Turboc 1.5 and am having problems linking files. I am writing
:a large application (over 64k) and am having trouble breaking up the file.
:The question is this, when I #include stdio, stdlib etc in multiple source
:modules the compiler and linker have no problems, however, this is not the
:case when i #include my own header files. The compile goes ok but the linker
:gives me the following error - "variable name here" is duplicated in module
:"source module name here" . This only occurs for my specfic header files not
:the system (stdio, etc). What can I do to get around this problem. Using
:extern may help but the header file is very large.
Variables can only be declaired once without the "extern" keyword. The
compiler's header files don't include any variables. That's why they compile
just fine. Your's shouldn't either, but if you must, do something like this...
----file.c----
#define _FILE
#include <file.h>
int var;
/* do more stuff */
---end file.c---
----file.h----
#ifndef _FILE
extern int var;
#endif
---end file.h---
---file2.c----
#include <file.h>
/* you can now use "var" */
---end file2.c---
Hope this makes some sense... I also could have sworn you had to do this
with typedefs, but I just tried something and it looks like maybe not. I
dunno. You'll have to try it yourself.
Frank Swarbrick (and his cat) swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"We've seen each other's hands. What else is there?"
mouse@mcgill-vision.UUCP (der Mouse) (05/18/88)
In article <28400001@ntvax>, john@ntvax.UUCP writes: > I am using Turboc 1.5 and am having problems linking files. I am > writing a large application (over 64k) and am having trouble breaking > up the file. [...] The compile goes ok but the linker gives me the > following error - "variable name here" is duplicated in module > "source module name here". It sounds as though you have run into the difference between the "def/ref" model of shared variables and the "common" model. The "common" model is the one UNIX has historically used; in this one, a variable can be defined in multiple files, as long as it is initialized at most once. In the "def/ref" model, a variable must be defined exactly once. Definition-by-example of terms: reference extern int i; definition int i; initialization int i = 5; Under UNIX, you could have multiple definitions and the loader would merge them, provided at most one of them was initialized. On other systems (apparently Turbo 1.5 falls into this category), we have the "def/ref" (definition/reference) model, where only one definition is permitted and other files must contain merely references. The K&R definition of C permits either model; presumably dpANS C does as well, though you would do well to use just the def/ref model when writing new code, because it works on both sorts of systems. Your header file should have externs; each variable must have exactly one definition, somewhere in one of the C files. (Which C file defines which variable doesn't matter from the linker's point of view, though good style of course says they should be grouped reasonably. I generally have one file which contains nothing but variable definitions.) der Mouse uucp: mouse@mcgill-vision.uucp arpa: mouse@larry.mcrcim.mcgill.edu
dcon@ihlpe.ATT.COM (452is-Connet) (05/19/88)
Several people have commented on the fact of extern... Here is a method I often use (this was also discussed some months back). [I tried to mail it to you, but the mail bounced.) In the main file I do: #define GLOBAL #include "file.h" #undef GLOBAL /* sometimes */ All other .c files just include file.h In file.h: #ifdef GLOBAL #define EXTERN #else #define EXTERN extern #endif EXTERN int variable; (etc) Now I can have all my variables in one place. Of course, if you need to initialize variables, that throws another wrench in the works, but one that can be handled by the same method. #ifdef GLOBAL #define EXTERN #define INIT(x) = x #else #define EXTERN extern #define INIT(x) #endif EXTERN int variable INIT(2); Hope this helps some (and doesn't open too big a can of worms here!) Dave Connet ihnp4!ihlpe!dcon
ljz@fxgrp.UUCP (Lloyd Zusman) (05/21/88)
In article <2955@ihlpe.ATT.COM> dcon@ihlpe.UUCP (David Connet) writes: > ... > Here is a method I often use ... > ... > In the main file I do: > > #define GLOBAL > #include "file.h" > #undef GLOBAL /* sometimes */ > > All other .c files just include file.h > > In file.h: > ... > #ifdef GLOBAL > #define EXTERN > #define INIT(x) = x > #else > #define EXTERN extern > #define INIT(x) > #endif > > EXTERN int variable INIT(2); Here's a slight variation that I use: #ifdef GLOBAL #define _ , /* allows you to init multilple values ... see below */ #define EXTERN #define INIT(x) = { x } /* note the braces */ #else #define EXTERN extern #define INIT(x) #endif EXTERN int variable INIT(2); EXTERN int array[] INIT( 1 _ 2 _ 3 _ 4 ); /* this works! */ I saw this on the net a year or two ago.
vlcek@mit-caf.UUCP (05/21/88)
People have been asking how to take care of external variables that must appear in #include files; namely, how does one declare them in the one file in which they are defined? The answer I have seen so far is to use #defines to flag to the #include file whether the current source file contains the variable definition or merely an external reference. Perhaps I am missing something, but this seems to me the wrong way to do things. For one thing, in a large application, one might need quite a few #defines to take care of all of the external variables, which may be interspersed through a number of #include files. The target of each #define would then have to be matched with its host #include file, which the programmer would have to inspect to find out initialization data, etc, etc. Good heavens! I am under the impression that there is nothing wrong with having an ``extern'' reference *and* a variable definition in the source file, and in fact I have done so in all of my C programming. So my #include files contain only ``extern'' references; I declare (and initialize) the variable in the proper source file, somewhere after the #include statement. Putting initialization data for a global variable into an #include file seems to me almost an act of violence! -- Jim Vlcek vlcek@caf.mit.edu !{ihnp4,harvard,seismo,rutgers}!mit-eddie!mit-caf!vlcek
gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/21/88)
In article <998@mit-caf.UUCP> vlcek@mit-caf.UUCP (Jim Vlcek) writes: >Putting initialization data for a global variable into an >#include file seems to me almost an act of violence! I don't know about violent, but it's a sure sign of source code out of control.
markhall@pyramid.pyramid.com (Mark Hall) (05/24/88)
In article <998@mit-caf.UUCP> vlcek@mit-caf.UUCP (Jim Vlcek) writes: >I am under the impression that there is nothing wrong with having an >``extern'' reference *and* a variable definition in the source file, >and in fact I have done so in all of my C programming. >-- >Jim Vlcek >vlcek@caf.mit.edu >!{ihnp4,harvard,seismo,rutgers}!mit-eddie!mit-caf!vlcek Your practice is OK according to K&R, pg 77: There must be only one `definition' of an external variable among all the files that make up the source program; other files may contain EXTERN declarations to access it. (There may also be an EXTERN declaration in the file containing the definition). On a related note, it's funny to watch how different compilers react to: main() { register int a; extern int a; } Some ignore the register directive and map `a' to some global variable of the same name. Others ignore the extern directive and create local references to `a'. I never could find out from K&R if this was an error, or if the `extern' should be ignored, or what. Can anyone comment? Just the facts, please. -Mark Hall
ckl@uwbln.UUCP (Christoph Kuenkel) (05/26/88)
In article <998@mit-caf.UUCP>, vlcek@mit-caf.UUCP (Jim Vlcek) writes: > I am under the impression that there is nothing wrong with having an > ``extern'' reference *and* a variable definition in the source file, > and in fact I have done so in all of my C programming. So my #include > files contain only ``extern'' references; I declare (and initialize) > the variable in the proper source file, somewhere after the #include > statement. Putting initialization data for a global variable into an > #include file seems to me almost an act of violence! I agree totally! Unfortunately, there are many compilers which do not :-( So regardless what whatever standard or K&R says, its *not* portable. -- Christoph Kuenkel ck@tub.BITNET Kantstr. 152 uunet!unido!tub!ck 1000 Berlin 12 {unido,tmpmbx,uwnue,bk35,tub}!uwbln!ckl West Germany -- Christoph Kuenkel ck@tub.BITNET Kantstr. 152 uunet!unido!tub!ck 1000 Berlin 12 {unido,tmpmbx,uwnue,bk35,tub}!uwbln!ckl West Germany
peter@ficc.UUCP (Peter da Silva) (06/02/88)
In article <7948@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <998@mit-caf.UUCP> vlcek@mit-caf.UUCP (Jim Vlcek) writes: > >Putting initialization data for a global variable into an > >#include file seems to me almost an act of violence! > > I don't know about violent, but it's a sure sign of source code out of > control. I disagree. It's a good idea to stick your declarations and initialisation in one place. When you change a variable, or add one, or delete one, you really need to make sure you get all the declarations. It's much more convenient if it's all in one place. But, do it intelligently: ---- foo.h #ifdef FOO_C #define GLOBAL #define INIT(x) =x #else #define GLOBAL extern #define INIT(x) #endif GLOBAL char *fooname INIT("foo"); GLOBAL char *footype INIT("program"); #undef GLOBAL #undef INIT ---- And then: ---- foo.c #define FOO_C #include "this.h" #include "that.h" #include "foo.h" #include "the_other.h" -- -- Peter da Silva, Ferranti International Controls Corporation. -- Phone: 713-274-5180. Remote UUCP: uunet!nuchat!sugar!peter.