Sep 242012
 
 September 24, 2012  Posted by at 11:37 pm Not So Stupid Questions  Add comments

[To celebrate my first year of programming I will ask a ‘stupid’ questions daily on my blog for a year, to make sure I learn at least 365 new things during my second year as a developer]

What are preprocessor directives?

What are preprocessor directives?

Another fancy word! During a region discussion earlier this year I came across something that looked like regions, preprocessor directives. Wow. Fancy words. Let’s try that again Pre-Processor-Directives. What is that? Well, regions are preprocessor directives if I’ve understood MSDN correctly, but they don’t do much – it’s more of an editor feature that sure sparked some debate on my blog a few days ago (37 comments so far :D!! ).

So what are preprocessor directives? I had to look this up, as I wasn’t quite sure, not 100%. (And please forgive my VERY simplified and short answer, it’s late, I’ve been working for 14 h non-stop and I am dead tired. I’ll work a bit more on this blog post later this week)

SO you have your code, the source code. When you compile and run that code you get your program (hopefully) up and running. So it’s the puzzle that pieces together your program. If you would like to treat some pieces of that puzzle differently by the compilator you can use preprocessor directives to tell the compiler how to treat that part of the code. For example, you might want to skip something during debug and debug only etc. Basically you have these ones to work with:

#if
#else
#elif
#endif
#define
#undef
#warning
#error
#line
#region
#endregion

Example from MSDN:

#define DEBUG
// …
#if DEBUG
Console.WriteLine(“Debug version”);
#endif

Pretty neat stuff I reckon! Have you used preprocessor directives? And what would be some great usage scenarios? I know my answer is very simplified, I tried to come up with a great explanation for how it works behind the scenes, but I got a tiny bit confused – and then I ran out of time and had to go to bed 🙂 Would love some more info about that, so please share if you have some great links!

  9 Responses to “Stupid Question 52: What are preprocessor directives? (In c#)”

  1. Unfortunately I also don’t have a link, but some historic information (just what pops into my mind).
    the preprocessors have been around for a long time. The first time I personally saw them was in the early 90s working with C, later C++.

    They basically help you controlling which parts of your code are going to be compiled. Maybe you could call it conditional compilation of your code. Often used to share code amongst platforms with small differences in code required.

    Hope I didn’t confuse more than explain 😉

  2. Hello, Iris) As I know, probably, the most used scenario is so-called “conditional compilation”. For example, at my previous job, we had some third-party component, which most of the team didn’t work with, and so, parts of code that use that component were under some #if use_component and so on. So, the most of the developers could build the project without that component. It is useful sometimes, but, as for me, there are also some great problems with that. With all these conditions a lot of chaos could be created, when you are not able to see clearly, what parts of code will be compiled now and what will be excluded. So, I would be very careful with that.
    For the alternative Debug scenario, I think, you could check these articles: Conditional Methods Tutorial, The Conditional attribute.
    Good luck!

  3. They’re actually quite useful in a variety of ways.

    You can output #warnings during compilation to the IDE output window (and the IDE Error List) e.g:
    #warning You've done something really hacky here!

    Or consider throwing a not implemented exception at runtime. Well the equivalent at compile time (which will halt compilation) would be:
    #if !MY_SYMBOL
    #error Compilation outside of debug
    #endif

    Then there is ignoring warnings that you are aware of (and want to ignore in an attempt to get to 0 warnings by fixing those you can, and accepting those you can’t)
    #pragma warning disable 414, 3021
    [CLSCompliant(false)]
    public class C
    {
    ...
    }
    #pragma warning restore 3021
    [CLSCompliant(false)] // CS3021
    public class D
    {
    ...
    }

    A list of warnings codes can be found here: http://msdn.microsoft.com/en-us/library/ms228296%28v=VS.90%29.aspx

    I use #if #else directives sometimes when refactoring code when I don’t want to create a new branch, or I want different behaviour from compilation symbols. Like, for example, to prevent any caching while debugging, or some other condition.

    #if STRONGER_CACHING
    Dictionary cache = new Dictionary();
    #endif

    public object MyMethod(string key)
    {
    object value = null;
    #if STRONGER_CACHING
    if(!cache.TryGetValue(key, out value))
    cache[key] = value = //...get from data store
    #else
    value = //...get from data store
    #endif
    return value;
    }

  4. We call them build flags at my work, as they only do stuff depending on the build configuration (e.g debug)

    And example where we have had to use these in the past is to handle some horribly written libraries from ComponentOne where the win-forms and web-forms dlls had exactly the same namespaces that would cause ambiguous name referencing. So when building a shared dll under a win-forms configuration, we used build flags to point to a correct wrapper class.

    It was extremely horrible and we walked away from those libraries as soon as we could.

  5. Hi,

    First of all, thank you for all your posts they are great!!! (answers from people toooo :p)

    For the preprocessor directives I have examples… with the “#if DEBUG”. My software is protected by a hardware key.
    So if I don’t pluged my key into the computer than my software will stop. In development mode, this is a pain in the ass!!!
    It’s also really usefull in debug mode to go where the application crash (yes sometime it crash…) but for user you want a nice error message… so here is how I start my app:


    var haveToCheckHardwareKey = true;
    #if DEBUG
    haveToCheckHardwareKey = false;
    Application.Run(new Screen.Principale(haveToCheckHardwareKey));
    #else
    try
    {
    Application.Run(new Screen.Principale(haveToCheckkey));
    }
    catch (Exception ex)
    {
    MessageBox.Show("Sorry... blablabla...", "Error");
    }
    #endif

    //JYC

  6. I’ve used them in the past when writing libraries that build both Windows and Silverlight versions. As Silverlight only supports a subset of .NET you sometimes need to code things differently and can take advantage of the fact that SILVERLIGHT is defined for Silverlight projects. So you end up with code like


    #if SILVERLIGHT
    // Silverlight specific code
    #else
    // normal code
    #endif

    Depending on which project is being built you get the correct code for it.

  7. In C and C++ the preprocessor is much more powerful than it is in C#. You could use it to write “macros” which look like functions, but are handled by simple text substitution:

    #define square(x) (x*x)

    int twentyfive = square(5);

    Now, in the early days, there was four distinct steps in compiling C code : Preprocessor, compiler, assembler, linking.

    The preprocessor , as it’s name implies, runs first, and handles the directive. The output of the above would be :

    int twentyfive = (5*5);

    The preprocessor knows nothing about the syntax of C, and could actually be used on non-C/C++ text files.

    The compiler, in those days, would output assembler code (as a text file). The assember would create the actual binary output. The linker merges in external libraries. (The C# compiler blurs these steps together).

    Preprocessor macros were always a problem, since they don’t follow scoping and naming rules, and are just simple text substitution. If you used the above macro like this:

    int xyxy = square(x+y);

    and you’ll get:

    in xyxy = (x+y*x+y);

    which is not the value I’d expect. In fact, you could write:
    char* shello = square(“Hello”);

    which will happily give you

    char* shello = (“Hello” * “Hello”);

    which is just a syntax error.

  8. […] Stupid Question 52: What are preprocessor directives? (In c#) (Iris Classon) […]

Leave a Reply to Jean-Yves Cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

What is 8 + 14 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)