external linkage of variable (IBM XL C++ on AIX)

T

Thomas Lenarz

Hello,

please forgive me for posting this if this problem has come up before.
I could not find any hint with google.

I am porting a bunch of source-code from SUN-OS to AIX at the moment
and have the following situation (simplified and renamed for better
understanding)


Source a.cc --> compiled and linked into a binary together with the
shared object underneath

.....
AnyType *globalAnyType;
....


Source b.cc --> compiled and linked into a shared object:

....
extern AnyType *globalAnyType;
....

globalAnyType = new AnyType(....); <----- Segment-Violation here


On SUN the code worked fine. On AIX I get no compile-errors and no
link errors. So I assume external references are resolved.

I found out using dbx that the assignment from "new AnyType(...)" to
globalAnyType causes the Segment-Violation. The external declared
globalAnyType appears not to be backed up by memory (dbx shows "nil").

To proove this I replaced globalAnyType by a non-extern-declared
variable of Type AnyType and....that works.

Does anyone have got an idea on why external binding of a variable
does not work in this case? Are there circumstances you can think of?

Might special compiler/linker options help?

I have to mention that I port from an old compiler without
namespace-support to a compiler with namespace-support. I already
checked if the variables may be in different namespaces because of
side effects of include files. But I concluded that this would be
logically impossible.

Thanks for any idea what I could try.

Cheers
Thomas
 
M

mlimber

Thomas said:
Hello,

please forgive me for posting this if this problem has come up before.
I could not find any hint with google.

I am porting a bunch of source-code from SUN-OS to AIX at the moment
and have the following situation (simplified and renamed for better
understanding)


Source a.cc --> compiled and linked into a binary together with the
shared object underneath

.....
AnyType *globalAnyType;
....


Source b.cc --> compiled and linked into a shared object:

....
extern AnyType *globalAnyType;
....

globalAnyType = new AnyType(....); <----- Segment-Violation here


On SUN the code worked fine. On AIX I get no compile-errors and no
link errors. So I assume external references are resolved.

I found out using dbx that the assignment from "new AnyType(...)" to
globalAnyType causes the Segment-Violation. The external declared
globalAnyType appears not to be backed up by memory (dbx shows "nil").

To proove this I replaced globalAnyType by a non-extern-declared
variable of Type AnyType and....that works.

Does anyone have got an idea on why external binding of a variable
does not work in this case? Are there circumstances you can think of?

Might special compiler/linker options help?

I have to mention that I port from an old compiler without
namespace-support to a compiler with namespace-support. I already
checked if the variables may be in different namespaces because of
side effects of include files. But I concluded that this would be
logically impossible.

Thanks for any idea what I could try.

Cheers
Thomas

So the new and the constructor succeeded, but the pointer assignment
failed? Is there any funky operator overloading related to AnyType? Can
you look at &globalAnyType (the address of your global) in your
debugger? Try reversing the two declarations by putting the actual
variable in b.cc and the extern declaration in a.cc. Now do you have a
problem with accessing it in the latter?

I'm guessing that this might be a weird symptom of an initialization
order fiasco (cf.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 and
following), and a different order of initialization allowed the code to
work on your other compiler but kills it here. Subtle things can happen
with the order of initialization. See the FAQ for a solution to such
problems.

You may also want to ask in a newsgroup related to your compiler (see
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9 for some
ideas).

Cheers! --M
 
T

Thomas Lenarz

So the new and the constructor succeeded, but the pointer assignment
failed? Yes!

Is there any funky operator overloading related to AnyType? No!

Can
you look at &globalAnyType (the address of your global) in your
debugger?
Yes!

Result is: definition in a.cc &globalAnyType: 47114711 (Can't remember
the exact number. But it appears to be a proper address.

extern declaration in bcc &globalAnyType: 0 (zero)
Try reversing the two declarations by putting the actual
variable in b.cc and the extern declaration in a.cc. Now do you have a
problem with accessing it in the latter?
Unfortunately I haven't had the time to try. But I will!
I'm guessing that this might be a weird symptom of an initialization
order fiasco (cf.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 and
following), and a different order of initialization allowed the code to
work on your other compiler but kills it here. Subtle things can happen
with the order of initialization. See the FAQ for a solution to such
problems.

You may also want to ask in a newsgroup related to your compiler (see
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9 for some
ideas).

Thanks a lot for your great hints and recommendations. I didn't know
the FAQ and about the initialization order fiasco. It's really
interesting and I will look into this a bit deeper.

But I'm a bit sceptical wether this is really the problem. In the end
"new AnyType(...)" is the only Object or Class-Reference involved and
globalAnyType is just a variable supposed to hold the pointer to the
AnyType-Instance.

For me it seems weird that the "extern declared globalAnyType"
doesn't have the the same address like the "defined globalAnyType"
after startup and the linker hasn't complained about anything
unresolved.

Thanks a lot for your help again. I will post the solution, when I
(hopfully) find it. :)

Cheers
Thomas
 
T

Thomas Lenarz

Source a.cc --> compiled and linked into a binary together with the
shared object underneath

.....
AnyType *globalAnyType;
....


Source b.cc --> compiled and linked into a shared object:

....
extern AnyType *globalAnyType;
....

globalAnyType = new AnyType(....); <----- Segment-Violation here


Does anyone have got an idea on why external binding of a variable
does not work in this case? Are there circumstances you can think of?

Might special compiler/linker options help?
Solution for this problem is:

There are different link-types on AIX for shared-libraries. In this
case it is necessary to use "Run-Time-Linking". This means that
symbolic information is resolved at program-load-time rather than
link-time.

This is forced by generating the the library with the exra option -G
and generating the main-application with the extra option -rtl.

Using "Default Linking" did not resolve the external variable
correctly.

I am sorry. I know it is OT here, but I just wanted to document the
solution for completeness.

Thomas
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top