Smit Ycyken
Smit Ycyken

Reputation: 1181

Macro NO_ERROR conflict

In winerror.h:

...
#define NO_ERROR 0L // dderror    
...                                         

In ErrorHelper.h :

...
namespace ErrorCodes
{
    enum Error
    {
        NO_ERROR = 0,// Not an error
        ...
    }
}
...

Even if #undef NO_ERROR is written before the namepsacethe conflict still appears.

How can it be possible to get rid of this macro conflicts?

Is it somehow possible to bypass macro like this?

#define min(a,b)            (((a) < (b)) ? (a) : (b))
...
(std::min)(a, b); // std::min used instead of evil macro

Error occures in every line with ErrorCodes::Error::NO_ERROR;:

Error   C2059   syntax error: '::'  

Error   C2589   'constant': illegal token on right side of '::' 

This conflict occurs with Visual Studio Compiler but compiles on Linaro GCC Snapshot 6.2-2016.11.

Upvotes: 1

Views: 2582

Answers (2)

Aconcagua
Aconcagua

Reputation: 25526

As Bathsheba mentioned already, you could #undef the pre-defined macro, however, I'd prefer not to do so; in general: especially if the values are not the same.

Still, you have another problem (which causes your compilation to fail even with the #undef): The scope of (classic) enum constants is not the enum, but its surrounding scope! So instead of ErrorCodes::Error::NO_ERROR, you need to refer to your enum values via ErrorCodes::NO_ERROR.

If you want to have scoped enums (since C++11), you need:

namespace ErrorCodes
{
    enum class Error
    //   ^^^^^
    {
        // ...
    };
}

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234715

You can't. Macros are a blunt tool that do all their damage before the C++ compiler gets to work. That's why it's good to minimise their use.

Assuming you don't want to suffer the renaming of your enum, value, you could always #undef NO_ERROR prior to your enum and in all places you use it.

With some toolsets supporting push and pop pragmas, this idea isn't too far-fetched.

Upvotes: 2

Related Questions