This is a mirror of official site: http://jasper-net.blogspot.com/

How does the C runtime know whether to use the static-linking or dynamic-linking version of the header file?

| Tuesday, March 22, 2011
In response to a description of what happens when you get dll­import wrong, nksingh asks, "This seems like a problem for the CRT. As far as I know, VC gives you the option of statically or dynamically linking the CRT. But it seems like the headers will have to make a choice to support one thing better than the other. Conditional compilation would work, but then people would have to remember to include a #define somewhere. Is this dllimport vs. static linking thing something the compiler could figure out on its own if you're doing Link-time codegen?"

Let's start from the beginning.

Yes, this would be a problem for the CRT since it wouldn't know whether to declare the functions as normal static functions or as dllimport-style functions, and the headers have to make a choice which way to go.

And if you look at the headers, you can see that it is indeed done via conditional compilation.

...
_CRTIMP int __cdecl fflush(FILE * _File);
...
This magic _CRTIMP symbol is defined in crtdefs.h like so:

/* Define _CRTIMP */
#ifndef _CRTIMP
#ifdef _DLL
#define _CRTIMP __declspec(dllimport)
#else  /* _DLL */
#define _CRTIMP
#endif  /* _DLL */
#endif  /* _CRTIMP */
Conditional compilation decides whether _CRTIMP expands to __declspec(dllimport) or to nothing at all, depending on whether the _DLL symbol is defined.

And yet nobody bothers writing #define _DLL before they #include <stdio.h>. There must be something else going on.

In fact, we can run some experiments to see what's going on.

#ifdef _DLL
#error "_DLL is defined"
#else
#error "_DLL is not defined"
#endif
Save this as dummy.c and run a few tests.

C:\tests> cl /MT dummy.c
dummy.c
dummy.c(4) : fatal error C1189: #error :  "_DLL is not defined"

C:\tests> cl /MD dummy.c
dummy.c
dummy.c(2) : fatal error C1189: #error :  "_DLL is defined"
Well how's about that. The compiler uses the /MT and /MD flag to decide whether or not to define the preprocessor symbol _DLL, which is the secret signal it passes to the crtdef.h header file to control the conditional compilation.

The compiler has to use this technique instead of deferring the decision to link-time code generation because it cannot assume that everybody has enabled link-time code generation. (Indeed, we explicitly did not in our sample command lines.)

If link-time code generation were enabled, then is this something that could be deferred until that point?

Posted via email from Jasper-net

0 comments: