June 2006 - Posts

Nish on the C++/CLI Support Library

I was just going to write about the C++/CLI Support Library included with Visual C++ 2005 when I noticed my friend Nish has already written a nice piece on the topic. Go check it out:

C++/CLI Library classes for interop scenarios


© 2006 Kenny Kerr

Posted by KennyKerr with no comments

Avoid dynamic disks if…

…you’re setting up Windows Media Center Edition.  This is one of those little tidbits you only learn after it’s too late. Although Windows Media Center Edition doesn’t have a problem with dynamic disks, the extender software (both first generation extenders and the Xbox 360) can’t tolerate them for some reason.

What would really be nice is if the Disk Management tool would actually warn you of this when you attempt to convert a basic disk to a dynamic disk. In some cases you simply can’t revert back and in my case resulted in hours of wasted time backing up data and then reinstalling Windows and all the applications on newly formatted hard drives.


© 2006 Kenny Kerr

Posted by KennyKerr with 3 comment(s)

Beyond WinFX: Transactions, Aero Wizards, And Task Dialogs In Windows Vista

The July 2006 issue of MSDN Magazine features my latest article where I talk about some of the new native APIs introduced with Windows Vista.

Beyond WinFX: Transactions, Aero Wizards, And Task Dialogs In Windows Vista

What comes to mind when you think about programming for Windows Vista? Odds are you’ll think of WinFX. WinFX encompasses a number of technologies that have been getting a lot of attention, including the Microsoft .NET Framework 2.0, Windows Presentation Foundation, Windows Communication Foundation, and Windows Workflow Foundation. But WinFX is only one part of the new OS. Windows Vista is a dramatic upgrade to the Windows operating system, providing a wealth of new and improved libraries and services that reach beyond WinFX, allowing you to build more powerful applications with less code.

This article introduces a number of new features that you can expect from Windows Vista. These features don’t normally get the attention they deserve because they’re either aimed at native C++ developers or just don’t fall into the category of WinFX programming. Nonetheless, they’re worth getting to know.


© 2006 Kenny Kerr

Posted by KennyKerr with 3 comment(s)

Attributes That Do Nothing

Some attributes in the .NET Framework don’t do anything. That is, there mere existence decorating your assemblies (and their types and members) has no discernable impact on runtime behavior. They are not used by the CLR for things like serialization and they are not used by applications through reflection. Pointless? Not at all.

A great example of this is the DebuggerDisplay attribute. It allows you to control how a variable is displayed in the debugger. Consider the following C# program:

enum SarcasmLevel
{
    Low,
    Medium,
    High
};

class Quote
{
    public string Statement;
    public SarcasmLevel Sarcasm;
}

class Program
{
    static void Main()
    {
        Quote quote1 = new Quote();
        quote1.Statement = "Veteran driver developers love the thought of UMDF.";
        quote1.Sarcasm = SarcasmLevel.High;

        Quote quote2 = new Quote();
        quote2.Statement = "UMDF threatens driver developer job security.";
        quote2.Sarcasm = SarcasmLevel.Low;

        Debugger.Break();
    }
}

Running this program in the debugger will result in a Locals window looking something like this:

 

Not especially useful. Now let’s add the DebuggerDisplay attribute.

[DebuggerDisplay("{Statement} Sarcasm: {Sarcasm}")]
class Quote
{
    public string Statement;
    public SarcasmLevel Sarcasm;
}

The next time you run the code the Locals window appears with much more useful information right off the bat.

Another handy attribute is the Conditional attribute. Consider the following program:

class Program
{
    static void ShareSecret(string secret)
    {
        Debug.WriteLine("About to share secret...");
        Debug.Assert(null != secret);

        if (null == secret)
        {
            throw new ArgumentNullException();
        }

        Console.WriteLine(secret);
        Debug.WriteLine("All done sharing secret.");
    }

    static void Main()
    {
        ShareSecret("I'm a closet C# developer.");
    }
}

The Debug class has a number of Assert and WriteLine overloaded methods all of which are attributed with the Conditional attribute to indicate that calls to those methods should only be included in the MSIL instruction stream produced by the compiler if a particular preprocessing identifier has been defined. The idea is that in release builds the ShareSecret method will be compiled to the MSIL equivalent of this:

static void ShareSecret(string secret)
{
    if (null == secret)
    {
        throw new ArgumentNullException();
    }

    Console.WriteLine(secret);
}

That’s certainly a lot more versatile than the macros you’d need to employ in C and C++ for conditional code. Speaking of C++...

If you’re a regular reader you may be wondering at this point why all my code samples are written in C#. The Visual C++ compiler has a dark little secret.

ShareSecret("Visual C++ ignores attributes that do nothing!");

Although it’s no surprise (unfortunately) that the Visual C++ managed code development experience isn’t as rich as the Visual C# development experience, it may come as a surprise that the following C++/CLI port of the C# ShareSecret method doesn’t do what you’d expect:

void ShareSecret(String^ secret)
{
    Debug::WriteLine("About to share secret...");
    Debug::Assert(nullptr != secret);

    if (nullptr == secret)
    {
        throw gcnew ArgumentNullException;
    }

    Console::WriteLine(secret);
    Debug::WriteLine("All done sharing secret.");
}

The problem of course is that the Visual C++ compiler leaves those “debug-only” statements in release builds and this causes undesired side-effects.

For starters, it will send the debug messages to any program monitoring debug output even in release builds. At best this is an annoyance. I certainly can’t stand programs that unnecessarily fill up my DebugView window when I’m busy debugging. It can also hurt performance and lead to more serious concerns such as inadvertent information disclosure.

Another problem is that it may well change your application’s behavior. Using an assertion to check function preconditions is a popular technique to quickly catch errors at runtime and direct the debugger to break at that point (instead of waiting for an exception to propagate). The subsequent if statement is there for release builds to guarantee the same preconditions in a programmatic and predictable manner. In other words, developers using this function expect it to throw an exception which they can catch and handle appropriately. Unfortunately, because Visual C++ doesn’t honor the Conditional attribute the exception cannot be handled before first being confronted by the breakpoint caused by the assertion.

And the solution is?

Well I’ve logged a bug with the Visual C++ team but it appears to not be a high priority item and won’t be fixed for the next release.

In the meantime there isn’t all that much that you can do short of providing a complete replacement for classes like the Debug class from the Diagnostics namespace. Using macros and the preprocessor isn’t very effective since the preprocessor has no understanding of overloaded functions. You end up having to pick one overload and sticking with it. For example, here is how you can implement the ASSERT macro for managed code:

#if _DEBUG
#define ASSERT(expr) System::Diagnostics::Debug::Assert(expr)
#else
#define ASSERT(expr) ((void)0)
#endif

What’s the moral of the story? Know what your compiler is doing. Don’t make assumptions about attributes targeted at compilers and linkers.


© 2006 Kenny Kerr

Posted by KennyKerr with 6 comment(s)
More Posts