There are different lib files based on settings - debug vs release, static vs dynamic. See that link I posted before - it lists various names. Thus the correct name is put in .obj file based on compilation settings.
Yes, that size reduction is mainly from CRT startup code. Because there's nothing else in main() that calls any CRT functionality - so that is automatically stripped out. There's no need to use nodefaultlib
if you have your own entry point. Linker will strip out everything automatically.
Be aware that if you're targeting modern Windows (Win 10 and up), then CRT is always present in windows. User does not need to install anything. You can just link to it dynamically and exe size will be tiny even if you call bunch of functions from CRT.
Regarding the executable size, It would be interesting to see comparisons between how each CRT feature that the compiler uses would affect the size. Based on my testing, __chkstk
and friends increase the size to around ~5.5KB. I couldn't test memset
for large array assignments because MSVC generated the rep
instruction directly on my machine.
Also, it seems like your guide has some weird formatting issues with the code, just in case you didn't know.
Be aware that if you're targeting modern Windows (Win 10 and up), then CRT is always present in windows. User does not need to install anything
What about before Windows 10? Were users forced to install the library, or did the devs have to ship the CRT dll with their apps? I do remember some common missing DLL bugs on those days.
__chkstk function is less than 100 bytes. There's no way it will give more than 5KB of code.
test.c
file:
int mainCRTStartup() { char big[4096]; big[sizeof(big)-1] = 1; }
cl test.c -GS- -link -subsystem:console
gives 2560 size executable. This is with __chkstk call, you can verify by stepping into asm.
Change 4096
to 2048
and then it won't use __chkstk. You can easily verify this by passing -nodefaultlib
after -link
argument. Same 2560 byte size for exe. No changes at all, because exe is created in 512 byte alignments. So previously __chkstk did fit into empty space there.
If you want to ship for pre-Windows 10 machines, then you either link to CRT statically (no dll files). Or put CRT redistributable dll files next to .exe. Or require user to install VS redistributable installer. All options will work fine, no missing dlls will happen.
I'm not sure why measuring size for this would matter. If you need CRT functionality then you use it. If you don't then you don't use it. If you would reimplement it yourself, then that would add size anyway. If you will implement same functionality it will add more or less same size. Sure, if you don't need exact same functionality then you will add smaller size.
I said __chkstk
and friends, which include ___report_rangecheckfailure
, ___security_cookie
, and __security_check_cookie
. When I said CRT size, I mostly talked about stuff that the compiler automatically inserts into your code (i.e __chkstk
in this case), not functions that you call explicitly by yourself. Also, is there any way to implement all the security functions yourself?
Sure, you can implement all of them yourself. If you know what they need to do, then you can write those functions with your own code.
Can you give me some overview on how these ___security_cookie
, ___report_rangecheckfailure
, etc functions work?
I have not looked into details how they work, I don't know.
But you can read up on that yourself in CRT source code. In these files:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\crt\src\vcruntime\gs_report.c C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\crt\src\vcruntime\gs_cookie.c
Path may have different version number depending on your installed VS version.
Guard Security would be my best guess on what it means. From here: https://learn.microsoft.com/en-us/cpp/build/reference/gs-buffer-security-check?view=msvc-170#gs-buffers