Archive

Archive for the ‘C++, VC++’ Category

Breakpoints in Windbg

January 15, 2011 Leave a comment

WinDbg rocks. 🙂 Setting breakpoints is very easy in WinDbg. The command to set a breakpoint is ‘bp’. So if you want to break whenever a dll is loaded into a process then type in following command…

bp kernel32!LoadLibraryW

So to trigger this breakpoint attach ‘notepad.exe’ to the debugger and then type in this command. Now let the app run (press F5). Goto File->Open (this will trigger a definite LoadLibrary :)). Now have a look in WinDbg which will have following output…

Breakpoint 0 hit
kernel32!LoadLibraryW:
00000000`76e50420 4533c0          xor     r8d,r8d

 To view call stack, type in ‘kpn’. I’ll blog more on breakpoints as and when I get time. Happy debugging. 🙂

Run to cursor feature in Visual Studio

January 6, 2011 Leave a comment

This is one cool feature of Visual Studio which I very much like, the shortcut for this feature makes life even more easy. 🙂 So what does this feature do?

Imagine we’re are stuck in a heavy duty for loop and you want to immediately break after the for loop but don’t want to traverse through the entire for loop iteration, move your cursor to the line below the for loop (of course it must be a c++ statement) and press Ctrl + F10. The result of this action is that the debugger will ‘execute’ (no it won’t skip) the entire for loop and break at the line that you chose.

I used to use this feature frequently so I guess this will help save sometime for you too.

Categories: C++, VC++ Tags:

Mandatory styles for a child dialog

If you are creating a dialog with style WS_CHILD then make sure you also have DS_CONTROL  and DS_CONTROLPARENT enabled for the dialog.

The reason being that the dialog at a time is a control (embedded inside another window) and a control parent (housing other controls). If these styles are not specified calls to GetWindowRect and then a subsequent ScreenToClient will return top co-ordinates in negative leading to some confusion.

Permutation combinations in Standard C++

January 19, 2010 2 comments

Recently one of my colleagues and also another user in MSDN forum asked a question related to this. The question is as follows…

If I have a string vector with few elements like “Nibu” “Babu” “Thomas”, how can I get all combinations of these three strings? Results should look like…

“NibuBabuThomas”
“NibuThomasBabu”
“BabuNibuThomas”
“BabuThomasNibu”
“ThomasNibuBabu”
“ThomasBabuNibu”

So in C++ there is a standard C++ algorithm function called next_permutation. Use this function on an array of sorted strings to get required result. So some sample code follows…

typedef std::string VT;
typedef std::vector< VT > VTVec;

// For dumping contents of vector to a stream
void Dump( VTVec& VecToPrint, std::ostream& stream )
{
  // Get iterator for given stream, every element will be separated with second
  // parameter.
  std::ostream_iterator<VTVec::value_type> Itr( stream, ", " );
  // Just one line to dump vector contents, no loops needed
  std::copy( VecToPrint.begin(), VecToPrint.end(), Itr );

  // Remove redundant space and bracket ( ", " ) from the end
  stream << "\b\b  \b\b\n";
}// End Dump

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  int nRetCode = 0;

  VTVec vecNames;
  vecNames.push_back("Nibu");
  vecNames.push_back("Babu");
  vecNames.push_back("Thomas");

  std::sort(vecNames.begin(), vecNames.end());

  std::cout << "\nNames before applying permutations: ";
  Dump(vecNames, std::cout);
  std::cout << std::endl;

  int Count = 0;
  while(next_permutation(vecNames.begin(), vecNames.end()))
  {
    Dump(vecNames, std::cout);
    ++Count;
  }

  std::cout << "\nFound a total of " << Count << " combinations!\n";
  return nRetCode;
}

Result is as follows…

How to create a unicode window in a non-unicode application?

December 22, 2009 Leave a comment

Recently a user asked this question in MSDN forums. He had MBCS enabled for his application and also wanted to enable unicode characters in a particular edit control. Note MFC only create unicode controls if UNICODE is defined in project settings.

So in order to explicitly create controls that support UNICODE characters we use the ‘W’ functions. For example: for our user he should use “CreateWindowW” function. Note the last ‘W’ in the function. ANSI windows are created by calling “CreateWindowA” function (this also means that we can explicitly create a non-unicode control).

Also make sure you use only UNICODE API’s for a control created in this manner. For e.g. always call GetWindowTextW instead of GetWindowTextA. Never use MFC on such a control if it’s not created by MFC framework, I mean don’t call CWnd::Attach on this control. Mainly because MFC is operating in non-unicode environment but our control is a UNICODE one.

Now once such a control is created you can paste characters of different languages, for e.g. Chinese, Japanese, etc even though the application is not a UNICODE supporting one.

Verify completeness of copy constructor

November 18, 2009 Leave a comment

So after sometime I’m back with a new tip. You know I sometimes forget to adapt copy constructors when I add new members to a class. So at times I end up with strange bugs. So I’ve devised a small utility to remind me to update copy constructors after adding new members to class. Here is the utility…

#ifdef _DEBUG
   #define VERIFY_COPY_CONSTRUCTOR(Class, OldSize)\
   if( sizeof( Class ) != OldSize )\
   {\
      TCHAR szBuf[512] = { 0 };\
      _stprintf_s(szBuf, \
                  sizeof(szBuf)/sizeof(TCHAR), \
                  _T( "Copy constructor not adapted for new members\nOld class size is: %d\nNew class size is: %d\n" ), \
                  OldSize, \
                  sizeof( Employee ));\
      ::MessageBox( ::GetForegroundWindow(), szBuf, _T( "Error!" ), MB_OK|MB_ICONERROR );\
      __asm int 3\
   }
#else
   #define VERIFY_COPY_CONSTRUCTOR(Class, Size)
#endif

class Employee
{
public:
   Employee()
   {
   }

   Employee( const Employee& Emp )
         : m_Name( Emp.m_Name )
   {
      // Actual size as of now is 36.
      VERIFY_COPY_CONSTRUCTOR( Employee, 32 );
   }

private:
   int m_Age;
   std::string m_Name;
};

Note: 32 is given on purpose to trigger an assert.

Now when you run this code an error pops up which says that copy constructor is not updated. Last time when I updated Employee class copy constructor I only added copying code for m_Name but now I’ve got a new member and I forgot to update the copy constructor. So my utility jumps in and gives me this error dialog…


Error Dialog

Error Dialog

 

Note that new size of the class is given in the message box to help you update the hard coded size in the macro. The only thing that you should remember here is to update the hard coded size in the macro (well you’ll that’s for sure ;)).

PS: There is also something cooler which I didn’t try out yet. VC10 has something called static_assert which will be useful for such purposes. You can try out and let me know ;).

#ifdef _DEBUG
#define VERIFY_COPY_CONSTRUCTOR(Class, OldSize)\
if( sizeof( Class ) != OldSize )\
{\
TCHAR szBuf[512] = { 0 };\
_stprintf_s(szBuf, sizeof(szBuf)/sizeof(TCHAR), _T( “Copy constructor not adapted for new members\nOld class size is: %d\nNew class size is: %d\n” ), OldSize, sizeof( Employee ));\
::MessageBox( ::GetForegroundWindow(), szBuf, _T( “Error!” ), MB_OK|MB_ICONERROR );\
__asm int 3\
}
#else
#define VERIFY_COPY_CLASS(Class, Size)
#endif

class Employee
{
public:
Employee()
{
}

Employee( const Employee& Emp )
{
VERIFY_COPY_CONSTRUCTOR( Employee, 35 );
}

private:
int m_Age;
std::string m_Name;
};

Categories: C++, VC++ Tags:

auto keyword redefined in VC10

auto keyword is one of those keywords that’s never used. So what the c++ committee has done is, they’ve started using it for a better purpose. For better understanding see this simple demo…

First without using auto keyword…

void AutoTest()
{
  typedef std::vector<int> IntVector;
  IntVector Ints;
  std::generate_n(std::back_inserter( Ints ), 100, rand);

  // After filling some elements into the vector, we iterate through them
  for( IntVector::iterator Itr = Ints.begin(); Itr != Ints.end(); ++Itr )
  {
    // Some code
  }
}

Now let’s try with the auto keyword…

void AutoTest()
{
  typedef std::vector</int><int> IntVector;
  IntVector Ints;
  std::generate_n(std::back_inserter( Ints ), 100, rand);

  // After filling some elements into the vector, we iterator through them
  for( auto Itr = Ints.begin(); Itr != Ints.end(); ++Itr )
  {
    // Some code
  }
}

Hope you noticed the difference, the type for the variable Itr is automagically inferred by the compiler based on the return type from Ints.begin().  Another huge benefit is when using auto keyword to wrap a lamda  expression (an anonymous/inline functor). See this example…

void LamdaTest()
{
int x = 0;
auto LamdaFunc = [&x](int y)
{
while( y– > 0 )
{
++x;
}
};

LamdaFunc( 10 );
LamdaFunc( 100 );

std::cout < < "Value of x after calling LamdaFunc is: " << x; }[/sourcecode] For us it's hard to infer or to know how to declare the type of this lamda expression but for the compiler it's easy (well hope so). When we give auto keyword the type is auto inferred. We then use LamdaFunc object to invoke this lamda expression. In the end x will have the value 110. Note that the expression [&x] means, pass x by reference. I'll brag about lamda's in my next post probably. Cool isn't it, I liked this feature. 8)

CComPtr vs _com_ptr_t

Recently a user asked this question in forums, I was quite able to answer his query. So thought this might be useful to you guys too. 🙂

So the basic difference is that CComPtr is an ATL class is used with using ATL COM implementations while _com_ptr_t is one of the few COM support classes to support non ATL COM development. The definitions of these COM support classes go along with the tlb files and probably that’s why they are called as COM support classes. Also their definition can be found in comdef.h too. The other classes similar to _com_ptr_t are …

  1. _bstr_t
  2. _com_error
  3. _com_ptr_t
  4. _variant_t

So what are COM support classes? These are special lightweight classes that wraps basic useful COM functionality so that ideas like COM smart pointer typedefs over raw COM inteface classes works just by using tlb file. An example on how _com_ptr_t is used…

_COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));

This above line declares _com_ptr_t specialization IMyInterfacePtr.

The library to link to for using COM support classes is comsuppw.lib.

Categories: C++, VC++, COM Tags: ,

std::string caveat

Never access an std::string‘s buffer with an intent to increase/decrease it’s length nor pass such a buffer to functions which takes a char*. I did this mistake sometime back and got trapped in a strange bug with operator +=. This is how my code looked.

std::string str( ' ', MAX_PATH );
GetFolderName( pFullPath, &str[0] ); // Oop

Problem with above code is that you won’t get an immediate crash since it’s a properly allocated buffer with MAX_PATH chars. But if you do further operations on such string expect plenty of inconsistencies. This is how my code looked after above piece of code…

str += "\\"; // Append backslash

I was expecting a valid path with backslash appended towards it’s end, but this never happened and debugging with debugger too didn’t help.

So now let me tell you what the exact problem is! When you do &str[0] you pass the address to the first char in std::string‘s buffer. So when function GetFolderName fills in this buffer with folder path the length of std::string is not updated since it’s a C style function and it’s neither expected to do so. So the function terminates given buffer with a ” with std::string‘s length way high (MAX_PATH). So now when I do a += std::string internally fails some condition leading to unexpected results, note that this piece of code never caused a crash but I was quite lucky and watchful enough to fix this stupid bug. Sigh!

So watchout, there is no CString::GetBuffer or CString::GetBufferSetLength type of function for std::string, well at least for now.

Project Conversion Bug in VS2008

May 11, 2009 1 comment

Are you having trouble with VS2008 after conversion from VS2005 to VS2008? Most common complaints are that the executable is way to slow when compared to it’s counterpart generated with VS2005. The reason for this is given in this MSDN forum thread have a look…

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/fb32033b-7bad-439b-a94c-943a17f0cbb2

The essence of this thread is given below (quote from the thread, thanks to Jon Baggott)…

In Visual Studio 2008 SP1 (SP1 not RTM) there is a serious bug with /O2 optimization. One way this bug can be triggered is by upgrading a project from a previous version. Even though the project setting shows the release build is set to /O2, the build can be not optimized at all. To work around it you have to change the setting to no optimization, apply, and then change it back to /O2. The quick way to see if this is needed is to check whether the setting for optimization is in bold or regular – if’s it’s bold you’re OK; if it’s regular text you’re not. This bug has been reported to Microsoft by many people over the past few months via the Connect feedback site but every case has been closed by them without doing anything and for completely invalid reasons.
%d bloggers like this: