Conflict caused by #define macro and enum using same name
Asked Answered
R

1

6

I am trying to integrate NVIDIA's PhysX into my Linux codebase. In some of its header files, it defines the following enums:

physxvisualdebuggersdk/PvdErrorCodes.h

struct PvdErrorType
{
  enum Enum
  {
    Success = 0,
    NetworkError,
    ArgumentError,
    InternalProblem
  };
};

physxprofilesdk/PxProfileCompileTimeEventFilter.h:

struct EventPriorities
{
  enum Enum
  {
    None,       // the filter setting to kill all events
    Coarse,
    Medium,
    Detail,
    Never       // the priority to set for an event if it should never fire.
  };
};

Which results in the following compile errors:

/usr/local/include/PhysX3/physxvisualdebuggersdk/PvdErrorCodes.h:36:4: error: expected identifier before numeric constant
    Success = 0,
    ^
/usr/local/include/PhysX3/physxvisualdebuggersdk/PvdErrorCodes.h:36:4: error: expected ‘}’ before numeric constant
/usr/local/include/PhysX3/physxvisualdebuggersdk/PvdErrorCodes.h:36:4: error: expected unqualified-id before numeric constant

and

/usr/local/include/PhysX3/physxprofilesdk/PxProfileCompileTimeEventFilter.h:46:4: error: expected identifier before numeric constant
    None,  // the filter setting to kill all events
    ^
/usr/local/include/PhysX3/physxprofilesdk/PxProfileCompileTimeEventFilter.h:46:4: error: expected ‘}’ before numeric constant
/usr/local/include/PhysX3/physxprofilesdk/PxProfileCompileTimeEventFilter.h:46:4: error: expected unqualified-id before numeric constant

I have determined that this is because X11/X.h #defines both 'None' and 'Success'. I have confirmed that this is the issue as, if I #undef both 'None' and 'Success', I no longer have the errors. However, this obviously isn't a desirable thing to do.

My question is: As a developer who has to use both these headers, what is the correct course of action for me to take? Should I report it to NVIDIA as a bug and wait for a fix or is there something that I can do myself to resolve the issue (besides #undef)?

Thanks for your time!

Ragsdale answered 30/12, 2014 at 17:2 Comment(11)
For one thing #define names should be in all caps. This normally eliminates these issues.Morton
@Morton Unfortunately those macros are defined in system header files, that can't (and shouldn't) be edited.Po
You have no choice than either use the #undef trick, or to rename your enumerations values, or to not include the X11 header files in the same files where your enumerations are used.Po
You could #undef them and then immediately re-#define them after the enum is declared. This is ugly, but not sure what else you can do.Polaroid
Can you included the X11 header after the PhysX3 header?Morton
@Polaroid The preprocessor will wrongly expand any uses of the enum afterwards though.Traitorous
re "this obviously isn't a desirable thing to do.", on the contrary, that's what you should do. also consider pimpl idiom to isolate those extremely low-quality headers.Hance
@πάνταῥεῖ: Unless you do the same thing every time the enum is used, which makes the solution even uglier...Polaroid
Thanks for the quick responses, guys - very much appreciated. I'll see if I have any luck changing the header order around. I'll also put it up on the PhysX forums - hopefully it'll help out the next guy who comes across this one. Thanks again! :)Ragsdale
@Cheersandhth.-Alf Yes - I suppose I wasn't thinking about it in the correct terms. There should be no detriment to #undef after the preprocessor's alredy expanded the macro where necessary, I imagine? Also, I hadn't heard of the pimpl idiom, so that's something I'll definitely look into.Ragsdale
I strongly support the idea of encapsulating the X11 stuff to isolate its dumb macros.Bertina
L
1

The sanest course of action is to separate the implementations in such a way that within your project you don't including BOTH conflicting headers in the same source file. One file deals with X and one with PhysX and then your application ties the two implementations together.

Lovettalovich answered 30/12, 2014 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.