#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

#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.

#500 – #define and #undef Must Be at Top of File

In C#, all #define and #undef  preprocessor directives must appear at the top of a source code file, i.e. before any valid C# tokens.  The definition (or un-definition) then remains in effect until the end of the file is reached.

#define QUIET

using System;
using DogLibrary;

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

In this case, because the conditional compilation symbol is included directly in the code, Intellisense already knows which of the two Bark methods will be included in the code.  It displays the line that will not be compiled in grey.

In this example, the second Bark method is not compiled at all.

 

#499 – Conditional Compilation Symbols Are Defined or Undefined

At any given point in your source code, while the compiler is compiling that section of code, a particular conditional compilation symbol is either defined or undefined.

You define a conditional compilation symbol

  • Using the #define preprocessor directive
  • Using the /define option on the compiler command line
  • Implicitly (for DEBUG and TRACE symbols), when selecting a build option for a project

You undefine a conditional compilation symbol

  • Using the #undef preprocessor directive
  • When reaching the end of a source file

A conditional compilation symbol is either defined or undefined–it has no value.

You check whether a conditional compilation symbol is defined by using the #if or #elif preprocessor directives.

A conditional compilation symbol remains defined in a source file until the end of the containing source file or until encountering an #undef directive (whichever comes first).