#509 – Use #pragma warning Directive to Disable Compile-Time Warnings

You typically want to fix any issues raised by the compiler as warnings at compile-time.  For example, the compiler might warning you that you declare a variable, but never use it.  In this case, you’d likely remove the variable declaration entirely.

There are times, however, when the compiler issues a warning about something that you know about and have no intention of “fixing”.  In the example below, we’ve implemented a CanBarkChanged event because it is part of an interface we are implementing, but we never fire the event.  The compiler warns us that we never fire this event.

Since we have no intention of firing the CanBarkChanged event, we can disable warning #67 when compiling this line of code, using the #pragma warning disable and #pragma warning restore directives.  We will then no longer get warning #67 for this line of code.

 

Advertisements

#508 – Using the #error and #warning Directives

The #error and #warning directives allow you to output errors and warnings at compile time.  You can give either directive some text that will be output by the compiler and look like a standard compile-time error or warning.

In the example below, we’ve include a compile-time warning, reminding us that we want to later change some code.

#warning TODO: Add a parameter to this Bark method
            d.Bark();

At compile time, we’ll see this warning in the Error List in Visual Studio.

You might use the #error directive to force an error to occur based on some combination of conditional compilation symbols.  When this directive is encountered, the compiler will generate an error.

#if DEBUG && BUILDFORRELEASE
#error You fool--Release builds must not be built with DEBUG flag!!
#endif

#507 – You can #define Other Symbols within a #if Block

Within the body of an #if/#endif pair, you can include #define or #undef directives.  If the body of the #if does contain #define or #undef directives, it must appear before the first token of the containing source file.

#define DOGSBARK

#if DOGSBARK || DOGSGROWL
#define DOGSMAKENOISE
#endif

using System;
using DogLibrary;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            Dog d = new Dog("Kirby", 12);
#if DOGSMAKENOISE
            d.BarkOrGrowl();
#endif
        }
    }
}

#506 – Using Expressions in #if and #elif Directives

You can use more complex expressions in #if and #elif directives, instead of just checking to see whether a single conditional compilation symbol is defined.

In the example below, the #elif directive triggers if the DOGSBARK symbol is defined and then DOGSGROWL symbol is not defined.

#define DOGSBARK
//#define DOGSWAG
//#define DOGSGROWL

using System;
using DogLibrary;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            Dog d = new Dog("Kirby", 12);

#if DOGSWAG
            d.WagTail();
#elif DOGSBARK && !DOGSGROWL
            d.Bark();
#else
            d.BarkAndGrowl();
#endif

        }
    }
}

You can build more complex expressions using parentheses and the && (logical AND) and || (logical OR) operators.

#if (DOGSWAG && DOGSDOTRICKS) || (DOGSDOEVERYTHING)
            d.WagAndFetch();
#endif

#505 – Using the #elif Directive

When you check whether a conditional compilation symbol is defined using the #if, #else and #endif directives, you can include additional clauses within the scope of the #if directive by using the #elif directive.  The #elif directive adds an additional expression to check, if any earlier expressions evaluate to false.

In the example below, we check both the DOGSBARK and the DOGSWAG symbols to determine which line to compile.

//#define DOGSBARK
#define DOGSWAG

using System;
using DogLibrary;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            Dog d1 = new Dog("Kirby", 12);
#if DOGSBARK
            d1.Bark();
#elif DOGSWAG
            d1.WagTail();
#else
            d1.JustSitThere();
#endif
        }
    }
}


You can include as many #elif clauses as you like.

#504 – Using the #else Directive

You can conditionally compile code using the #if and #endif preprocessor directive.  You can also use an #else clause between the #if and the #endif.

In the code below, we’ve commented out the definition of DOGSBARK, so the code between the #else and #endif will be compiled.

//#define DOGSBARK

using System;
using DogLibrary;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            Dog d1 = new Dog("Kirby", 12);
#if DOGSBARK
            d1.Bark();
#else
            d1.WagTail();
#endif
        }
    }
}

Note that the code after the #if directive is greyed out, while the code after the #else is formatted normally.

#503 – Conditionally Compile Code Using #if / #endif Directives

Once you define a conditional compilation symbol using the #define directive, you can use the #if directive to conditionally compile code when the corresponding conditional compilation symbol is defined.

In the code sample below, the Dog.Bark method is called, because the DOGSBARK symbol is defined and so the line containing the call to Bark is compiled.

#define DOGSBARK

using System;
using DogLibrary;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            Dog d1 = new Dog("Kirby", 12);
#if DOGSBARK
            d1.Bark();
#endif
        }
    }
}

If we don’t define the DOGSBARK symbol, then the compiler doesn’t compile the line between the #if and #endif directives.  In fact, since the compiler doesn’t even look at these lines in this case, they don’t even have to contain valid C# syntax.