NeonGlow
NeonGlow

Reputation: 1692

GCC build. Expected error

I am not an expert in any of the languages or GCC. So my question might be sub-par.

I am building a code base with thousands of CPP files using GCC. In a file say A.cpp I am calling some functions in B.cpp [B.cpp contains class method definitions for a class defined B.h]. The build was Ok. But then I excluded B.o from the makefile. So now object file B.o is not created. But in this case I was expecting an error at compilation or linking stage since A.cpp is referring functions from B.cpp. But there was none and the code still builds without errors. But when I moved the fn calls from A.cpp to another file C.cpp it gave me a linker error which is what I believe, the expected behavior.

Is this the expected behaviour? Also I checked a map file created during build, which listed all the function names, and the functions from B.cpp was present in the map even though the object file for B.cpp was not created. So my question is why there was no errors when I called functions from a file that is not part of the build. I tried deleting all the object files and binaries from the previous builds to clean up any residues that may exist, but to no avail. I am having no clues. Can anyone offer some help?

In my map file, normal functions are listed like

80010820 T __gccmain

80010828 t __gccmain_end etc

But the fns from B.cpp is listed as

U CNvThread::ProcMsgReq(unsigned, void*)

U CNvDbMgrThread::Singleton(unsigned long)

Upvotes: 1

Views: 142

Answers (3)

NeonGlow
NeonGlow

Reputation: 1692

The expected errors were ignored by the linker since the line that created A.o was not compiled in because of a #if.

#if (OBJ_A_SUPPORTED)

A* a = new A();

#endif

The header file in which OBJ_A_SUPPORTED define was moved.

This led the linker to exclude fns from A.cpp and in turn removed the call to fns in B.cpp. So there was no linker errors. A good look at the map file may yield some clues in such cases which I totally missed out.

Upvotes: 0

paulsm4
paulsm4

Reputation: 121809

It sounds like you have a "makefile": good.

By default, "make" will (usually) try to build your project. That's the standard convention, anyway.

Typically, make will also have other "targets". For example, you could type "make clean" or "make cleanall". If these targets existed, they would delete your binaries, so you could rebuild from scratch.

I suspect when you re-ran "make", it picked up the old binary from your last build. Did you check if it exists?

Otherwise, I guess your project never actually needed it in the first place :)

Running "ld -M" to generate a map (which should include a cross-reference) is a good way to confirm this.

Upvotes: 1

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137517

If B.o was still there from the previous build, it will link against the old copy just fine (unless something major changed). If you didn't build the final executable, and only A.o, then that's still no problem because A.o references the functions from B, but isn't linked up with them until the final output file link.

Again, if B.o was still there from the previous build, it will be used, which is why it showed up in the map file.

Upvotes: 1

Related Questions