In what order are translation units linked?

I have a VStudio 2019 project with many .cpp files. I copied some code and did some chnages and now I am getting a linker error like so:


main already defined in sss.obj


I can certainly search the prject for main and find the duplicate, so this is an easy case. But it would be so nice if I could know the order in which the objs are considered for linking. I would only have to look at objs picked for linkage after sss.obj.

Anybody know the order chosen by the IDE?

Regards,
Juan
But you're using a file search, right? You're not opening each file manually and searching for the symbol name, are you?
Last edited on
you are correct - maybe this is the not the best example .... I only want to know the order of obj linking: is it the order they appear in the solution explorer in VStudio 2019?

Regards,
Juan
If that's not the reason, then why do you need to know that?

If I had to guess, I'd guess it's completely arbitrary. They're probably linked in whatever order is returned by the directory iteration function.
> main already defined in sss.obj
Either you have two main() functions.

Or you have the bad habit of having #include "file.cpp" all over the place.

Or you have actual source code in header files.

Changing the order of object linkage will just turn
main already defined in sss.obj
into
main already defined in foo.obj

You either need to fix the source, to find your multiple definitions of main.
Or fix your project so it only compiles the source you actually need.
It depends on your compiler, but usually the files are linked in the order that they occur on the command line. For object files, it makes little difference because the linker links the entire contents of file, but for libraries, it's very important because the linker links only the library objects that contain undefined symbols found up to that point.

For example, suppose you have:
1
2
main.cpp:
extern int i;


and in library liba:
1
2
int i;
int j;


and in library libb:
int j;

So main needs something in liba, and liba needs something in libb.

If you link in this order: main, libb, liba then the linker won't know about int j until it links in liba. And since it already searched libb before int j was known about, you'll end up with an "undefined variable" error.

On the other hand, if you link in this order: main, liba, libb then everything will be fine.
If you're using Visual Studio, the error message should provide the info you require.

e.g. (when I copied void CAboutDlg::DoDataExchange(CDataExchange* pDX) into another file)

1>------ Build started: Project: Vocab_App_Dlg, Configuration: Release Win32 ------
1>Vocab_App_DlgDlg.cpp
1>Vocab_App_DlgDlg.obj : error LNK2005: "protected: virtual void __thiscall
  MFCGUI::CAboutDlg::DoDataExchange(class CDataExchange *)"
  (?DoDataExchange@CAboutDlg@MFCGUI@@MAEXPAVCDataExchange@@@Z)
  already defined in AboutDlg.obj
1>C:\Source\Scratch\Bin\Release\Vocab_App_Dlg.exe : fatal error LNK1169:
  one or more multiply defined symbols found
1>Done building project "Vocab_App_Dlg.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 4 up-to-date, 0 skipped ==========

Tells me that it's in both Vocab_App_DlgDlg.cpp and AboutDlg.cpp

Andy
Last edited on
If that's not the reason, then why do you need to know that?


A very distant memory of optimizing the link order by hand for performance (trying to remember what it did, maybe helped to avoid far pointers or page faults or something like that?)

I don't think we care anymore, but it was once an area you could tinker with.
thanks!
Topic archived. No new replies allowed.