Showing posts with label Visual Studio. Show all posts
Showing posts with label Visual Studio. Show all posts

Friday, September 10, 2010

VC++ Directories in Visual Studio 2010

The default include, lib, etc… directories in Visual Studio 2010 are no longer project dependent.  You can, if you need to, over-ride the settings on a per project basis.  The directory settings are stored in the following location:

%USERPROFILE%\AppData\Local\Microsoft\MSBuild\v4.0

In this directory you will find the files:  Microsoft.Cpp.Win32.user.props, Microsoft.Cpp.x64.user.props, and Microsoft.Itanium.user.props  (the last two only if you have installed the x64 tools).

These files are UTF-8 encoded XML files.  In them you can define your include, lib, executable, reference, and source paths.  You can also define excluded directories.  These settings become the defaults for all C++ projects.  Of course the Win32 file is for 32 bit Windows builds, while the x64 file is for 64 bit AMD64 builds.  I don’t know anyone that has an Itanium computer so I won’t even discuss those.

This is great now that you don’t have to search and replace through every .vcproj file (I know .vcxproj file in 2010) every time you want to change an include path.  Just change the paths in these files and all projects are updated.

Teams:
You can store your Microsoft.Cpp.xxx.user.props files in source control.  Each team member can pull down the required files so that everyone is on the same path (bad pun, couldn’t resist).

Thursday, January 28, 2010

Exceptions: Win32 Structured Exceptions, C++ Exceptions, and Compiler Options.

In a Windows program that is written in the C++ language there are two types of exceptions that can be handled. The first is the Win32 structured exception that is built into the OS. The second are the C++ exceptions that are generally classes derived from std::exception.

To handle a Win32 structured exception you would have code like so:

__try {
// here is my code.
} __except(EXCEPTION_EXECUTE_HANDLER) {
// handle the exception here
}

To handle a C++ exception you would have code like this:

try {
// here is my code.
}
catch(std::exception &e) {
// handle exception here, should handle specific
// exceptions that you expect in production code
}
catch(...) {
// handle any other type of exception
// i.e. not derived from std::exception
}

The question is: What happens when a win32 SE is thrown and you are using C++ exceptions?

The answer: It depends on your compiler options!

Project Properties->Configuration Properties->C/C++->Code Generation->:Enable C++ Exceptions:

The choices are:
No
Yes (/EHsc)
Yes with with SEH Exceptions (/EHa)

If you use the setting No, you will get compiler warning C4530 for using C++ exceptions when they are not enabled. If you are treating warnings as errors like all professional programmers do, then you fix this compiler setting before going on. Runtime behavior is similar to Yes (/EHa).

If you use the setting Yes (/EHsc) C++ exceptions will be caught in catch handlers as you would expect. Win32 Structured Exceptions WILL NOT BE CAUGHT even by a catch(...) block!

If you use the setting Yes(/EHa) C++ exceptions will be caught in catch handlers as you would expect. Win32 Structured Exceptions WILL BE CAUGHT in catch(...) handlers only.

The moral of this story is: use the Yes(/EHa) setting at all times!

With the use of the Yes(/EHa) setting, you can use the function _set_se_translator to register a function that would be responsible for translating all Win32 structured exceptions into C++ exceptions. This helps to unify the error handling framework. Now you can use strongly typed C++ exceptions throughout your program. You should never have to use a catch(...) block again!

Example:

void my_translate(unsigned int code, _EXCEPTION_POINTERS *ep)
{
std::runtime_error re("translated win32 SE");
throw re;
}

// ... somewhere in WinMain... 
_set_se_translator(my_translate);

In Windows each thread has its own translator function which means that you must install your translator on each thread that you create.