| Title: | C++ | 
| Notice: | Read 1.* and use keywords (e.g. SHOW KEY/FULL KIT_CXX_VAX_VMS) | 
| Moderator: | DECCXX::AMARTIN | 
| Created: | Fri Nov 06 1987 | 
| Last Modified: | Thu Jun 05 1997 | 
| Last Successful Update: | Fri Jun 06 1997 | 
| Number of topics: | 3604 | 
| Total number of notes: | 18242 | 
  $ cxx/version nl:
  DEC C++ T5.5-004 on OpenVMS VAX T7.0
I hope this question isn't too rudimentary. I tried to find an answer in other
notes and couldn't. I am trying to declare an object name "globalIa" of a class
type "IntArray" in a C++ main() module (x.cxx) and reference it in another
module (xx.cxx). The problem is that the link gets an undefined symbol being
referenced in the second (xx.cxx) module. I declared a global integer "i" using
the same technique and it *is* visible to both modules. If I comment out the
references to globalIa and rebuild the value assigned to the integer in the main
module is seen in the other module so I know it's working.
How can I properly declare "globalIa" and build the following code fragment so
the same "globalIa" object is visble to both modules?:
$ TYPE x.cxx
  #include "intarray.h"
  #include "xx.h"
  // Want to be able to access this global integer in another module.
  int i = 999;
  // Want to be able to access this global object in another module.
  IntArray globalIa();
  main()
  {
  aroutine();
  }
$ TYPE xx.h
  void aroutine();
$ TYPE xx.cxx
  #include "intarray.h"
  #include <iostream.h>
  extern int i;
  extern IntArray globalIa;
  void aroutine()
  {
  cout << "aroutine entered. i is " << i << endl;
  cout << "globalIa.getSize() is " << globalIa.getSize() << endl;
  }
$ TYPE x.opt
  x
  xx
  intarray
$ SET VERIFY
$ LINK/DEBUG X/OPT
  x
  xx
  intarray
  %LINK-W-NUDFSYMS, 1 undefined symbol:
  %LINK-I-UDFSYM,         GLOBALIA
  %LINK-W-USEUNDEF, undefined symbol GLOBALIA referenced
        in debug or traceback record
        in module XX file DKA300:[ZIELONKO.DECCPP]XX.OBJ;3
  %LINK-W-USEUNDEF, undefined symbol GLOBALIA referenced
        in psect $CODE offset %X000000CB
        in module XX file DKA300:[ZIELONKO.DECCPP]XX.OBJ;3
I tried it as follows too with no difference:
$ link/debug x/opt
  UNIVERSAL=globalIa
  x
  xx
  intarray
  %LINK-W-NUDFSYMS, 1 undefined symbol:
  %LINK-I-UDFSYM,         GLOBALIA
  %LINK-W-USEUNDEF, undefined symbol GLOBALIA referenced
        in debug or traceback record
        in module XX file DKA300:[ZIELONKO.DECCPP]XX.OBJ;3
  %LINK-W-USEUNDEF, undefined symbol GLOBALIA referenced
        in psect $CODE offset %X000000CB
        in module XX file DKA300:[ZIELONKO.DECCPP]XX.OBJ;3
$ run x/nodebug
  aroutine entered. i is 999
  %SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=00000000,
  PC=00000689, PSL=03C00004
  %TRACE-F-TRACEBACK, symbolic stack dump follows
  module name     routine name                     line       rel PC    abs PC
  XX              IntArray::getSize                  38      00000009  00000689
  XX              aroutine                         6184      00000061  0000071D
  X               main                               64      00000028  00000630
  globalIa.getSize() is
Thanks in advance,
Karol
Here is intarray.h in case anyone needed to see it. I do not include
intarray.cxx as I am confident that it works properly and didn't want to muddle
up this note too badly. If you need to see it I can post it too.
$ ty intarray.h
// Assignment 2
//
// Header file for IntArray class
//
#ifndef _INTARRAY_H_
//
// IntArray.h
//
#define _INTARRAY_H_
const int ArraySize    = 12;
const int MaxArraySize = 65535;
const char ArrayName[] = "Default";
class IntArray
{
public:
        // Default Constructor
        IntArray();
        // Constructor
        IntArray( const char *name, unsigned int sz = ArraySize );
        // Destructor
        ~IntArray();
        // Routine to print to default output
        void print();
        // Overloaded operator[]
        int &operator[]( int );
        int *operator[]( long );
        // "normal" inlined member function
        int getSize() { return m_size; }
private:
        // member data
        unsigned int m_size;
        int *m_ia;
        // The following data member should be declared const
        // but we are not ready to initialize const data members
        // yet (there's special syntax needed that we have not
        // covered yet). So far now, drop the const
        //const char *m_name;
        char *m_name;
};
#endif
| T.R | Title | User | Personal Name | Date | Lines | 
|---|---|---|---|---|---|
| 3412.1 | I think your declaration of globalIa is wrong... | DECC::J_WARD | Mon Jan 27 1997 10:01 | 12 | |
| // Want to be able to access this global object in another module. IntArray globalIa(); This declares a function called globalIa which takes no arguments and returns a IntArray. I think you meant: IntArray globalIa; // notice no parens Judy | |||||
| 3412.2 | (notes collision)But in x.cxx you declared globalIa to be a Function! | WIDTH::MDAVIS | Mark Davis - compiler maniac | Mon Jan 27 1997 10:20 | 41 | 
| >  // Want to be able to access this global object in another module.
>  IntArray globalIa();
--------------------^^
This is a function prototype, promising a function that returns an object
of type IntArray; this is NOT the definition of a global object!
If you remove the "()", the linker will be very happy, and your program
will work fine.
[Notice your xx.h, which contains the function prototype for "aroutine":
>$ TYPE xx.h
>  void aroutine();
this has the same syntactic form as "IntArray globalIa();"]
OR, if you have an IntArray constructor that takes an argument, eg.,
        IntArray(int);
and your definition of globalIa contains an argument:
	 IntArray globalIa(10);
then this will Also cause globalIa to be a global object.
Unfortunately in C++, there is syntactic ambiguity between declaring an
object initialized with a NO argument
	 IntArray globalIa(/* object, call constructor with no argument*/);
                           
and a funtion prototype:
	 IntArray globalIa();
and since the latter is left over from C, the "ambiguity" is "defined" to be
a function prototype.
Mark Davis
c/c++ team
 | |||||
| 3412.3 | That did it. Thanks | UCXAXP::ZIELONKO | Mon Jan 27 1997 13:03 | 18 | |
| >> // Want to be able to access this global object in another module. >> IntArray globalIa(); > > >This declares a function called globalIa which takes no arguments >and returns a IntArray. > >I think you meant: > >IntArray globalIa; // notice no parens Oops, duh. That fixed it. I thought I was doing something silly. I was trying to force the default constructor for the IntArray class to be used and somehow thought that was the syntax. Oh well. Thanks, Karol | |||||