I have a Dllmain that allocates Thread local storage when a thread attaches to this DLL. Code as below:
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
LPVOID lpvData;
BOOL fIgnore;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
onProcessAttachDLL();
// Allocate a TLS index.
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return FALSE;
// how can it jump to next case???
case DLL_THREAD_ATTACH:
// Initialize the TLS index for this thread.
lpvData = (LPVOID) LocalAlloc(LPTR, MAX_BUFFER_SIZE);
if (lpvData != NULL)
fIgnore = TlsSetValue(dwTlsIndex, lpvData);
break;
...
}
I know that for the main thread, the DLL_THREAD_ATTACH is not entered, as per Microsoft Documentation. However, the above code worked. I am using VC2005. When I entered the debugger, I saw that after it entered DLL_THREAD_ATTACH case when ul_reason_for_call = 1! How can that happen? If I add `break’ at the end of DLL_PROCESS_ATTACH block, the DLL failed to work.
How can this happen?
If I understand you correctly, you are wondering why, after entering the
DLL_PROCESS_ATTACHcase, the execution continues on theDLL_THREAD_ATTACHcase, instead of after the end of theswitch.This behaviour is called “fall through”, and it is standard C. Without an explicit
breakstatement, the execution continues on the nextcase.Of course, it is quite counterintuitive for programmers who see it the first time, so it is a constant source of misunderstanding and even bugs (you may not always know whether the
breakwas left out intentionally, or by mistake). It is considered good practice, therefore, when using this construct, to mark it explicitly with a comment, like: