Memset on objects will result in crash? Then none of your MFC apps will work.

25 03 2008

Icon Description
While stepping from C to the C++ world, it’s the first pitfall that we encounter – initializing an object with memset. Since memset if faster, we used to initialize objects like this,

CObject obj;
memset( &obj, 0, sizeof(obj));

More than enough for a crash! Because if the class contains virtual functions, then the first 4 bytes holds the pointer to vtable. If we use memset, then the vtable pointer will be overwritten to 0 and it may end up in crash.

But, do you know one thing? The famous MFC framework uses memset to initialize some of its objects such as CDialog, CScrollView etc. Can’t believe? It does, but safely. Without damaging the vtable pointer.

icon_underthehood.jpg
If you check the constructor of CDialog, you can see one macro – AFX_ZERO_INIT_OBJECT();. This macro calls memset internally. See the implementation of macro below.

// zero fill everything after the vtbl pointer
#define AFX_ZERO_INIT_OBJECT(base_class) \
memset(((base_class*)this)+1, 0, sizeof(*this) - sizeof(class base_class));

But it’s safe. Because it skips the vtable ptr.

Icon Note
Don’t try this macro in your source. Because CDialog doesn’t contain any objects as members. It contains just some pointers and handles. If your object contain some class variables as members which contain virtual table, then that vtable ptr may be overwritten. Take care!

Advertisements




Trigraph char sequences in C & C++

25 03 2008

Icon Description
There are some triplet character sequences present in C & C++ to represent some special punctuation characters. The trigraph sequences are used for compatibility of source code written in ISO 646 or EBCDIC charset.

icon_underthehood.jpg
// Is this a valid statement? I can’t believe. But for compiler is valid.
??=define arraycheck(a,b) a??(b??) ??!??! b??(a??)

But when we apply trigraph sequence, the above code block became as follows.
// Wow!!! It’s a valid one…
#define arraycheck(a,b) a[b] || b[a]

Please see list of trigraph sequences below.
Trigraph Punctuation Character

??=	            #
??(                 [
??/                 \
??)                 ]
??’	            ^
??<                 {
??! 	            |
??>	            }
??- 	            ~

And one trigraph pitfall.
// Whether the following line compiles ???????/
cout << “Whether you can see this message?”;

Find your answer and take care trigraphs next time…
Thanks to Wiki for examples and the list.





Watch heap objects eventhough the symbol went out of scope.

25 03 2008

Icon Description
While debugging we want to watch some objects through out. An object can be watched only with its symbol and it should be valid in the current stack frame. For instance,

CJobManager* CJobManager::GetJobManager
{
    return m_pJobManager;
}

For watching the JobManager instance, we need the symbol m_JobManager in this stack frame. When the function leaves, we can’t see the JobManager instance anymore. So how can i watch these heap objects without the symbol in stack frame?

Icon How Can I Do It?
1) Get the address of your heap object. Just add to watch window and get the location. For instance assume its 0x00034de0.
2) Now add a new entry to the watch window like this – (CJobManager*)(0x00034de0)
3) Now eventhough your function returns and you loss the symbol, still you can see your heap object.

Really helpful isn’t it? i was fed up with the global objects in my project and atlast find this method to watch them premenently.





Interlocked family of functions for simple Synchronizations.

24 03 2008

Icon Description
In multithreaded environment we usually use Mutex to synchronize access to resources. But sometimes our resources may be a single integer member variable which holds some count or like that. For such light weight resource, using mutex is not preferred.

Icon How Can I Do It?
For that you can Interlocked family of functions. Please see some of the functions below.

InterlockedIncrement()
InterlockedDecrement()
InterlockedExchange()
InterlockedCompareExchange()
InterlockedExchangePointer()
…

For example if you need to increment a member variable threadsafely, you can use InterlockedIncrement(). That function will ensure the thread synchronization without any additional kernel objects such as mutex etc… Please see the code block below.

long m_lCount = 0;
...
// Increment the value.
InterlockedIncrement( &m_lCount );




Do you know what is MZ?

24 03 2008

Icon Description
If you open any windows executable in some text editor you can see the executable starts with two chars – “MZ”. Do you know what it is ?

icon_underthehood.jpg
Windows executables are in PE( Portable Executable) file format. For backward compatibility with dos, the PE file format contains a small MS-DOS stub in the starting. That’s why when we run any windows application in DOS, it just print an error message that, it needs windows to execute the application.

The dos header starts with a special signature – “MZ”. MZ stands for Mark Zbikowski. He is one of the earlier Microsoft Architects and the designer of Dos Executable file format. In 2006 he was honored for 25 years of service with the company, the first employee to reach this milestone other than Bill Gates and Steve Ballmer 🙂 Digging history is Interesting… isn’t it ?





RunDll32.exe – The key to windows treasure chest.

24 03 2008

Icon Description
While digging the C:\Windows directory, a windows enthusiast surely will encounter the application RunDll32.exe. If executed it seems to do nothing. But its a key to great windows treasures. Still don’t believe me ? okay run the following command in your command prompt.
RUNDLL32.exe user32.dll, LockWorkStation

icon_underthehood.jpg
Actually speaking, RunDll32.exe is just a program which executes the specified funciton of the specified dll, passed via command line arguments. Please see the syntax as follows.
RUNDLL32.EXE dll_name, EntryPoint <Optional Arguments>

The only requirement is that the callable function’s prototype should be as follows.
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

Window had implemented lot of functinalities inside which can be callable via RunDll32.exe. See some e.g. below.

RunDll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3 Shows the System Properties, Advanced tab.
RunDll32.exe shell32.dll,Control_RunDLL hdwwiz.cplInvokes Add new hardware wizard

Please refer http://www.dx21.com/SCRIPTING/RUNDLL32/REFGUIDE.ASP for huge list of features that can be accessed via RunDll32.

Usages:

1) You can create a shortcut for RunDll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3 by which we can easly take the environment variables tab.
2) You can write some test functions in your dll and we can call it anytime anywhere without exe file.

The usages are many, only limitation is our imagination… 😉





Easy Compilation guards instead of #ifndef macros

24 03 2008

Icon Description
Did you ever noticed the following lines in the your header file?

#ifndef _MYHEADER_H_
#define _MYHEADER_H_
   ...
#endif

They are protection macros to protect the header file from multiple compilation. Assume your header file is included many time in different CPP. if you are not using these protection macros, your header file will be included more than once and will give you a Multiple declaration error. To prevent that, these macros are being used. But there is a more simple method in VC++ compiler extension.

Icon How Can I Do It?
You can use #pragma once in your header file. E.g.

#pragma once
   ...

If you use #pragma once, then the header file will be included only once in your compilation.