MSVC++ and constructors

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
cinculator

MSVC++ and constructors

Post by cinculator »

Does anybody know how does MSVC++ call constructors and destructors for global objects? ???
And don't tell to look how DJGPP does! :-X
DJGPP does NOT handle it same way. :-\
Tim

Re:MSVC++ and constructors

Post by Tim »

Look in the VC++ runtime source code. If it's not installed, you can install it from the CD.

I'd say the compiler puts constructors (or at least stubs that call constructors) in specially-named sections. The linker probably sorts sections with names similar to these alphabetically; in particular, the .CRT$XCA section will appear first and the .CRT$XCZ section last. All these .CRT sections get merged into a data section in the final EXE, but in the correct order.

cinitexe.c defines these variables:

Code: Select all

#pragma data_seg(".CRT$XCA")
_CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL };

#pragma data_seg(".CRT$XCZ")
_CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = { NULL };
To call the constructors, all the startup code needs to do is treat __xc_a to __xc_z as an array, and call any non-null elements (function pointers) within the array.

I think the destructors work by the constructor calling atexit on the destructor code.

Hopefully this will become clear if you step through the source code of a program compiled using VC++. I'm not sure of the details but that's how I understand it to work. gcc's method is similar, but with different names. Note that the method VC++ uses might vary between different versions.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:MSVC++ and constructors

Post by Solar »

Tim Robinson wrote: Note that the method VC++ uses might vary between different versions.
Also note that the standard compliance of MSVC++ is poor. That is usually not a problem when you are aware of such details and working in application space, but when working with the innards of the compiler and the binaries, it can become a real pain.

(At work we are running a dual environment, working on the same code under Sun CC / Solaris and MSVC++ / Windows. Code that is 100% standards compliant and running well under Solaris doesn't compile under MSVC++, which frequently gives us headaches. Not that Sun CC or gcc are perfect, they are just... better. At least in that department.)
Every good solution is obvious once you've found it.
Tim

Re:MSVC++ and constructors

Post by Tim »

Did you try VS.NET 2003? Do you have access to the Whidbey alpha? I'd be interested to see how they compare to the standard -- Whidbey is supposed to be fully compliant apart from export.
cinculator

Re:MSVC++ and constructors

Post by cinculator »

OK! Here comes a better question: "How does VC++ make code to call a function?"
Look at this:

Code: Select all

int main()
{
   Proces1();
   return 0;
}
objdump says this:

Code: Select all

.
.
.
.
Disassembly of section .text:

00000000 <_main>:
   0:   55                       push   %ebp
   1:   8b ec                   mov    %esp,%ebp
   3:   e8 00 00 00 00          call   8 <_main+0x8>
   8:   33 c0                   xor    %eax,%eax
   a:   5d                      pop    %ebp
   b:   c3                      ret
I don't understand this ??? ??? ???
Tim

Re:MSVC++ and constructors

Post by Tim »

The instruction that's calling the function is the CALL line. It doesn't say the word 'Proces1' there because you're looking at a .OBJ file, which hasn't been linked. Presumably the Proces1 function is in a different file, so the compiler has written a dummy address there and made a note in the .OBJ file which causes the linker to insert the real address of Proces1 there.

The other instructions are normal function prolog and epilog.
cinculator

Re:MSVC++ and constructors

Post by cinculator »

If it's a dummy address then I'll have to change linker!
It wasn't a good idea to mix ld and cl ;)
I'm trying to translate my code from DJGPP to MSVC++ so I tried to mix them to save my time BUT......
So what linker should I use ?

THANKS.
Tim

Re:MSVC++ and constructors

Post by Tim »

Nononono... don't worry -- this is normal. What you're looking at isn't a program, but a prototype for a program. It's just one part. That .OBJ file doesn't know about the other .OBJ files that you might link with it. When the compiler writes the .OBJ file, it can't know the real address of the Proces1 function, so (as I said) it writes a dummy address AND A NOTE TO TELL THE LINKER TO INSERT THE REAL ADDRESS OF PROCES1 THERE.

The output from objdump isn't telling you the whole story. It's treating what you've given it as a whole program -- it's not. It only becomes a program once it's been linked, using the linker, with the .OBJ files that contain these missing functions.

On a different note, people have reported problems with mixing ld and cl. cl has a different idea of the COFF format from ld. A Windows version of ld (such as Mingw or Cygwin) should recognise this Win32 COFF format.
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:MSVC++ and constructors

Post by kataklinger »

I know what is linker, obj files, call instr. I do this job many years...
What I'm saying : if cl generates at different way that address (Win32 COFF format) maybe ld couldn't recognize that.

If objdump can't recognize it why should ld ???

I'm also cicnulator but I found my password
Tim

Re:MSVC++ and constructors

Post by Tim »

There's nothing here to say that ld can't recognise it. Disassembling a .OBJ file is meaningless. The instructions are right but the addresses are wrong. Link the .OBJ files together, produce a real executable (EXE, ELF, binary, whatever) and look at that.
Post Reply