home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!usc!elroy.jpl.nasa.gov!nntp-server.caltech.edu!eql.caltech.edu!rankin
- From: rankin@eql.caltech.edu (Pat Rankin)
- Newsgroups: comp.os.vms
- Subject: External objects in C
- Followup-To: comp.os.vms
- Date: 14 Dec 1992 19:35 PDT
- Organization: California Institute of Technology
- Lines: 52
- Distribution: world
- Message-ID: <14DEC199219350160@eql.caltech.edu>
- References: <PRZEMEK.92Dec9100328@rrdstrad.nist.gov> <PRZEMEK.92Dec14171154@rrdstrad.nist.gov>
- NNTP-Posting-Host: eql.caltech.edu
- News-Software: VAX/VMS VNEWS 1.41
-
- [was Subject: Re: Why does this code crash with ACCVIO? (summary, solution)]
- In article <PRZEMEK.92Dec14171154@rrdstrad.nist.gov>,\
- przemek@rrdstrad.nist.gov (Przemek Klosowski) writes...
- > Anyone cares to speculate why a separate keyword is
- > needed, rather than having "external" cause linking?
-
- There are several different models for external objects. The one
- used by VAX C--and by GNU C for compatibility--is equivalent to Fortran
- COMMON blocks, doubtlessly for greater ease in multi-language applications.
- This is equivalent to using a named PSECT instead of a global symbol in
- Macro32; C's globaldef/globalref is vice versa. If you had a Fortran
- BLOCK DATA module for data initialization you would have seen the same
- problem, except that the other declarations of the object in Fortran would
- have had to specify the proper size so the symptoms you'd see would have
- been different (zeroed data with your initialization missing, rather than
- ACCVIO due to wrong object size).
-
- This is usually only a problem with data-only object modules. There
- are several ways around it. Suppose FOO.C has just global variables in it.
- 1) explicitly link the data, either as a separate object file foo.obj or
- as an explicit library reference. link ...,mylib/libr/include=foo
- Some people seem to be unaware of the latter variant. xxx.olb/incl=yyy
- is about the same as yyy.obj, but xxx.olb/lib/incl=yyy is more like
- yyy.obj,xxx.olb/lib.
- 2) don't use data-only modules; always specify an initialization routine
- even if it doesn't do anything. Modify foo.c by adding
- `void foo_init(void) { return; }' and add a call to `foo_init()'
- in main() or some other appropriate place. This is the method I prefer
- because it's portable and the linker will complain if I don't supply
- foo.obj (which can easily happen if relinking by hand instead of using
- a make utility).
- 3) like #2, but use a globaldef variable and put a globalref reference
- to it somewhere. The somewhere could be in a header file used by all
- the modules, so is more transparent than a dummy initialization routine,
- but also non-portable.
- Both the second and third choices will allow the linker to pull module foo
- out of an object library without specifying the extra /include qualifier.
- With #3, be careful that GNU C's optimizer doesn't omit your unreferenced
- external(s) from the object module(s) though.
-
- DEC C for Alpha/VMS treats external objects differently by default,
- and has a qualifier called "/extern_model" for controlling it. The options
- are "common_block", "relaxed_refdef", "strict_refdef", and "globalvalue".
- According to the online help, there's also a variant of strict_refdef
- which takes an extra name value, but I'm not sure offhand what that does.
- Relaxed_refdef is the default and requires that at least one definition
- exist (rather than the all `extern <type> <object>'; declarations such
- as you ended up with when the linker didn't bring in your data-only
- module). Strict_refdef requires exactly one definition, which is what
- portable code should have anyway.
-
- Pat Rankin, rankin@eql.caltech.edu
-