I am reading Microsoft’s CRT source code, and I can come up with the following code, where the function __initstdio1 will be executed before main() routine.
The question is, how to execute some code before entering the main() routine in VC (not VC++ code)?
#include <stdio.h> #pragma section('.CRT$XIC',long,read) int __cdecl __initstdio1(void); #define _CRTALLOC(x) __declspec(allocate(x)) _CRTALLOC('.CRT$XIC') static pinit = __initstdio1; int z = 1; int __cdecl __initstdio1(void) { z = 10; return 0; } int main(void) { printf('Some code before main!\n'); printf('z = %d\n', z); printf('End!\n'); return 0; }
The output will be:
Some code before main! z = 10 End!
However, I am not able to understand the code.
I have done some google on .CRT$XIC but no luck is found. Can some expert explain above code segment to me, especially the followings:
- What does this line
_CRTALLOC('.CRT$XIC') static pinit = __initstdio1;mean? What is the significance of the variable pinit? - During compilation the compiler (cl.exe) throws a warning saying as below:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80×86 Copyright (C) Microsoft Corporation. All rights reserved.
stdmacro.c stdmacro.c(9) : warning C4047: 'initializing' : 'int' differs in levels of indirection from 'int (__ cdecl *)(void)' Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:stdmacro.exe stdmacro.obj
What is the corrective action needs to be done to remove the warning message?
Thanks in advance.
Added:
I have modified the code and give type to pinit as _PIFV. Now the warning message is gone.
The new code is as follows:
#include <stdio.h> #pragma section('.CRT$XIC1',long,read) int __cdecl __initstdio1(void); typedef int (__cdecl *_PIFV)(void); #define _CRTALLOC(x) __declspec(allocate(x)) _CRTALLOC('.CRT$XIC1') static _PIFV pinit1 = __initstdio1; int z = 1; int __cdecl __initstdio1(void) { z = 100; return 0; } int main(void) { printf('Some code before main!\n'); printf('z = %d\n', z); printf('End!\n'); return 0; }
There’s some information here (search for CRT). The significance of variable
pinitis none, it’s just a piece of data placed in the executable, where the runtime can find it. However, I would advise you to give it a type, like this:The linker warning probably just warns you you have a function that has
intreturn type, but doesn’t return anything (probably you’d better change the return type tovoid).