Fmt: Type enumeration conflicts with Mathcad's MCADINCL.H

Created on 18 Apr 2016  路  10Comments  路  Source: fmtlib/fmt

On line 967 of format.h, an enumerated value _STRING_ is used. However, Mathcad uses a pre-processor define for STRING in MCADINCL.H. _STRING_ is then replaced by it's value (8) by the pre-processor and format.h fails to compile with an error that an unexpected constant was found in the enumeration. The enumeration is shown here:

enum Type { NONE, NAMED_ARG,
// Integer types should go first,
INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
// followed by floating-point types.
DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
CSTRING, _STRING_, WSTRING, POINTER, CUSTOM
};

This was discovered when trying to compile the current development version of CoolProp as a Mathcad DLL add-in.

Most helpful comment

You could simply put that in a proxy header and include the proxy all over instead.

All 10 comments

I suggest #undefining the Mathcad's STRING macro before including format.h or changing the include order so that format.h is included before MCADINCL.H.

IOW don't use bad libraries

I did a little research today. The Mathcad #define STRING 8 is used to give your custom Mathcad functions a flag to tell what type of variable you are passing. The other two types are COMPLEX_SCALAR (to indicate a COMPLEXSCALAR type) and COMPLEX_ARRAY (to indicate a COMPLEXARRAY type). The STRING value indicates an MCSTRING type, so it should have probably been (using the previous convention) MC_STRING instead of just STRING.

Without this, you have to hard code an 8 into the function, which is a bad idea.

However, the line can be changed to #define MC_STRING 8 with no affect, other than you have to now use MC_STRING to define your user functions. I'll go this route, but there should be some documentation to this affect in the Mathcad wrapper docs. This also means that every time a new version of Mathcad is installed, mcadincl.h will have to be mod-ed with this change. Not ideal.

I also put this change into PTC as a suggestion for a code improvement, but that would potentially break a LOT of people's legacy codes that are using STRING instead of MC_STRING.

Victor, I'll see if the include order can be reversed. That may be a better solution, but should also be documented if it works.

I think you can avoid hardcoding 8 by creating a little wrapper for mcadincl.h with something like

#include <mcadincl.h>
enum { MC_STRING = STRING };
#undef STRING

Then you won't need to change mcadincl.h and the namespaces won't be polluted with the STRING macro.

You could simply put that in a proxy header and include the proxy all over instead.

Nice! I love hanging out with smart people!

I suppose that warrants a close as this issue isn't really an issue, and in any case is an easy problem to avoid

Yes. I'll doctor up the Mathcad wrapper in CoolProp and make a pull request there to fix this conflict.

thanks, i have seen the solution, but i can't change old codes usage (there has a lot of modules).
case:
main.cpp

undef BOOL

include "format.h"

BOOL b; // also cause compile error

@vitaut

You can do something like

typedef BOOL MY_BOOL;
#undef BOOL;

in a header that wraps the legacy code and then use MY_BOOL (or whatever name you've come up with, you can even use a namespace instead of a prefix) in your code.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gabime picture gabime  路  12Comments

AlexFundorin picture AlexFundorin  路  12Comments

jk-jeon picture jk-jeon  路  15Comments

avikivity picture avikivity  路  22Comments

jiri picture jiri  路  22Comments