Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

#Actuale‍dd

Posted 25 November 2012 - 09:03 AM

Good examples of the namespacing problem come directly from Microsoft's <windows.h> header itself.

I bet many people here have hit the problem of trying to std::numeric_limits<int>::max(), or std::max(a, b) after #include-ing <windows.h>, only have the compiler to spit a weird error at them. This is because <windows.h> uses the preprocessor to define 'min' and 'max' macros.

Another example of preprocessor damage, also caused by <windows.h>:

#include <windows.h>

namespace fs
{
    bool DeleteFile(const fs::Path &amp;amp;filename)
    {
        // ...
    }
}

This won't compile without additional hacks. This is because <windows.h> uses the preprocessor to define "DeleteFile" as either "DeleteFileA" or "DeleteFileW", depending on whether or not you've defined UNICODE. I've even gone to the care of putting my DeleteFile in its own namespace. But it doesn't make a difference to the preprocessor.

Not only does the preprocessor not respect C++ namespaces, but there's no way of putting macros themselves in to any kind of namespace, meaning that everyone has to (or really should) add a prefix to the front of their macros.

So <windows.h> is a horrible header. I could list a number of other real-world examples where it has damaged perfectly reasonable code. I actually have a policy to never include it in a public header because of the carnage it can cause. I would not recommend using it for inspiration!

Though sometimes useful, the preprocessor should be avoided where possible, especially if there's an alternative, which in this case there is. Use "const int MAX_INTS = 1000;" instead. You really shouldn't be worrying about wasting 4 bytes here or there.

#2e‍dd

Posted 25 November 2012 - 08:55 AM

Good examples of the namespacing problem come directly from Microsoft's <windows.h> header itself.

I bet many people here have hit the problem of trying to std::numeric_limits<int>::max(), or std::max(a, b) after #include-ing <windows.h>, only have the compiler to spit a weird error at them. This is because <windows.h> uses the preprocessor to define 'min' and 'max' macros.

Another example of preprocessor damage, also caused by <windows.h>:

#include <windows.h>

namespace fs
{
    bool DeleteFile(const fs::Path &amp;filename)
    {
        // ...
    }
}

This won't compile without additional hacks. This is because <windows.h> uses the preprocessor to define "DeleteFile" as either "DeleteFileA" or "DeleteFileW", depending on whether or not you've defined UNICODE. I've even gone to the care of putting my DeleteFile in its own namespace. But it doesn't make a difference to the preprocessor.

Not only does the preprocessor not respect C++ namespaces, but there's no way of putting macros themselves in to any kind of namespace, meaning that everyone has to (or really should) add a prefix to the front of their macros.

So <windows.h> is a horrible header. I could list a number of other real-world examples where it has damaged perfectly reasonable code. I actually have a policy to never include it in a public header because of the carnage it can cause. I would not recommend using it for inspiration!

Though sometimes useful, the preprocessor should be avoided where possible, especially if there's an alternative that avoids it, which in this case there is. Use "const int MAX_INTS = 1000;" instead. You really shouldn't be worrying about wasting 4 bytes here or there.

#1e‍dd

Posted 25 November 2012 - 08:54 AM

Good examples of the namespacing problem come directly from Microsoft's windows.h header itself.

I bet many people here have hit the problem of trying to std::numeric_limits<>::max(), or std::max() after #include-ing <windows.h>, only have the compiler to spit a weird error at them. This is because <windows.h> uses the preprocessor to define 'min' and 'max' macros.

Another example of preprocessor damage, also caused by <windows.h>:

#include <windows.h>

namespace fs
{
    bool DeleteFile(const fs::Path &filename)
    {
        // ...
    }
}

This won't compile without additional hacks. This is because <windows.h> uses the preprocessor to define "DeleteFile" as either "DeleteFileA" or "DeleteFileW", depending on whether or not you've defined UNICODE. I've even gone to the care of putting my DeleteFile in its own namespace. But it doesn't make a difference to the preprocessor.

Not only does the preprocessor not respect C++ namespaces, but there's no way of putting macros themselves in to any kind of namespace, meaning that everyone has to (or really should) add a prefix to the front of their macros.

So <windows.h> is a horrible header. I could list a number of other real-world examples where it has damaged perfectly reasonable code. I actually have a policy to never include it in a public header because of the carnage it can cause. I would not recommend using it for inspiration!

Though sometimes useful, the preprocessor should be avoided where possible, especially if there's an alternative that avoids it, which in this case there is. Use "const int MAX_INTS = 1000;" instead. You really shouldn't be worrying about wasting 4 bytes here or there.

PARTNERS