[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::c_plus_plus

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

3412.0. "How to make class object globally visible in multiple modules?" by UCXAXP::ZIELONKO () Mon Jan 27 1997 12:34

  $ 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.RTitleUserPersonal
Name
DateLines
3412.1I think your declaration of globalIa is wrong...DECC::J_WARDMon Jan 27 1997 13:0112
 
 // 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::MDAVISMark Davis - compiler maniacMon Jan 27 1997 13:2041
>  // 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.3That did it. ThanksUCXAXP::ZIELONKOMon Jan 27 1997 16:0318
>> // 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