Link B before A

Started by
8 comments, last by Yratelev 20 years, 3 months ago
Hi, In Visual Studio 6, C++, the files link in alphabetical order. How do you over ride that? I have 2 global objects A and B. A needs B constructed so it can retrieve information, but since B hasnt been constructed yet, it crashes. Of course I can rename all my classes, but that sounds pretty stupid, and not all the classes are mine to rename anyway thanks Stu PS: anyone know how to define "user defined keywords" in VS6? Cos in options u can change their font colour and that would be ahndy, if i knew how to declare them. [edited by - Yratelev on January 23, 2004 3:16:50 PM]
Yratelev
Advertisement
I''m not sure linking is your problem the way you describe it. If the problem is a crash during the program running because of the order of global variable construction then there''s not much you can do about it. The standard doesn''t specify the order they are constructed in.

what most people end up doing is wrapping them in a class and then contstructing them in the void main(...) method.

Cheers
Chris
CheersChris
You can''t control the construction order of C++ globals (which doesn''t necessarily have anything to do with the order in which they are linked). The general solution is to use a singleton object instead that will create the object on demand.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]
According to the standard, the order in which static objects in different files are linked is unspecified. It is, therefore, bad practice to write C++ programs that depend upon the order in which static objects in different files are linked.

// A.cppextern int B;int A = B;// B.cppint initB (){  return 7;}int B = initB(); 


In this simplification of your problem, the value of A is undefined.

You have two obvious options. You may put A and B in the same file (via #inclusion, perhaps), or you may check that B is initialised, and initialise it if it is not.

Something along the lines of:

// A.cppextern int getB();int A = getB();// B.cppextern bool initB();bool bIsInitialised = initB();bool initB (){  if (!bIsInitialised)    B = 7;  return bIsInitialised = true;}int B;int getB (){  initB();  return B;} 



CoV
CoV
Try putting both (all) globals in a class or namespace called "Global". Alternativly, you could use global pointers, which get new-ed at the beginning of the program -- in the correct order. I advocate namespaces though.



-----------
VenDrake

"When you and a friend are being chased by a King Cheata, you have but one chance, trip your friend."
-------------VenDrakeTo understand recursion, you must first understand recursion.
quote:Original post by VenDrake
Try putting both (all) globals in a class or namespace called "Global".

To put them both in a class would require that they be compiled as the same translation unit. If that were happening, then there wouldn''t be a problem.

Although you can define members of namespaces in seperate files, that doesn''t cause them to be initialised in the correct order.
quote:
Alternativly, you could use global pointers, which get new-ed at the beginning of the program -- in the correct order.

Well, no, they don''t. They get new-ed in an arbitrary order. If you follow this advice, you will crash your program.

A quick tip to posters: don''t post a solution to a problem unless you''ve successfully used that solution yourself.

CoV
CoV
quote:Original post by Mayrel
quote:Alternativly, you could use global pointers, which get new-ed at the beginning of the program -- in the correct order.

Well, no, they don''t. They get new-ed in an arbitrary order. If you follow this advice, you will crash your program.

i think he meant to use global pointers, and new them at the beginning of main() or WinMain() in the proper order (since global pointers are just that, and don''t create objects unless you tell them to).

anyway, i second the singletons suggestion. that is part of the reason they exist.
--- krez ([email="krez_AT_optonline_DOT_net"]krez_AT_optonline_DOT_net[/email])
Don''t use globals. If you really care about this project than take the effort and pass them as parameters. However, if it''s just a 2 day thing then it doesn''t really matter.
quote:Original post by Mayrel
quote:Original post by VenDrake
Try putting both (all) globals in a class or namespace called "Global".

To put them both in a class would require that they be compiled as the same translation unit. If that were happening, then there wouldn''t be a problem.

Although you can define members of namespaces in seperate files, that doesn''t cause them to be initialised in the correct order.


You are correct. By this suggestion, I was infering that the variables need to be declared within the same unit. It''s usually not too hard to make that change. You could simply declare them within the same unit without using a class/namespace, but I find there are hidden advantags to using a container for your globals.

quote:Original post by Mayrel
quote:Original post by VenDrake
Alternativly, you could use global pointers, which get new-ed at the beginning of the program -- in the correct order.

Well, no, they don''t. They get new-ed in an arbitrary order. If you follow this advice, you will crash your program.


Maybe I wasn''t clear. "At the beginning of the program" means main() or an initialization function. Basically some place dedicated to non-arbitrary initaliziation.



-----------
VenDrake

"When you and a friend are being chased by a King Cheata, you have but one chance, trip your friend."
-------------VenDrakeTo understand recursion, you must first understand recursion.
if you are using a MS compiler, there are pragmas which you can use to control the order of initialization:
#pragma init_seg (whatever)
GCC has something similar, involving some kind of priority level, but I cant remember it. there have been past posts on this topic - search for them.

This topic is closed to new replies.

Advertisement