When will _ATL_ALLOW_UNSIGNED_CHAR work?
Asked Answered
B

1

5

I'm migrating a Visual C++ project which uses ATL/MFC from VS2010 to VS2013. The project compiles with /J ("assume char is unsigned"), and there is too much code that may or may not rely on that fact to easily remove the compiler flag.

Under VS2013, /J causes a compiler error in atldef.h: ATL doesn't support compilation with /J or _CHAR_UNSIGNED flag enabled. This can be suppressed by defining _ATL_ALLOW_UNSIGNED_CHAR. Microsoft mention this in the MSDN documentation for /J, along with the vague statement: "If you use this compiler option with ATL/MFC, an error might be generated. Although you could disable this error by defining _ATL_ALLOW_CHAR_UNSIGNED, this workaround is not supported and may not always work."

Does anyone know under what circumstances it is safe or unsafe to use _ATL_ALLOW_CHAR_UNSIGNED?

Bluh answered 2/12, 2014 at 9:40 Comment(3)
Can't answer your question, but is it viable to #define and #undef as required for your own non-ATL code?Adagio
#define and #undef what, exactly?Bluh
#define and #undef _CHAR_UNSIGNED exactly. That's what the /J option does. Or maybe .. MS Connect says "The /J switch controls the signed-ness of char. Setting the define is a side-effect of passing /J in that it is used by limit.h, but just setting the macro does not change the behavior of char" which is more worrying.Adagio
J
10

Microsoft struggles to keep ancient codebases, like ATL, compatible with changes in the compiler. The principal trouble-maker here is the AtlGetHexValue() function. It had a design mistake:

The numeric value of the input character interpreted as a hexadecimal digit. For example, an input of '0' returns a value of 0 and an input of 'A' returns a value of 10. If the input character is not a hexadecimal digit, this function returns -1.

-1 is the rub, 9 years ago that broke with /J in effect. And it won't actually return -1 today, it now returns CHAR_MAX ((char)255) if you compile with /J. Required since comparing unsigned char to -1 will always be false and the entire if() statement is omitted. This broke ATL itself, it will also break your code in a very nasty way if you use this function, given that this code is on the error path that is unlikely to get tested.

Shooting off the hip, there were 3 basic ways they could have solved this problem. They could have changed the return value type to int, risking breaking everybody. Or they could have noted the special behavior in the MSDN article, making everybody's eyes roll. Or they could have invoked the "time to move on" option. Which is what they picked, it was about time with MSVC++ being the laughing stock of the programming world back then.

That's about all you need to fear from ATL, low odds that you are using this function and easy to find back. Otherwise an excellent hint to look for the kind of trouble you might get from your own code.

Junkie answered 8/12, 2014 at 13:21 Comment(1)
This is the quality knowledge that makes StackOverflow so useful. Thanks - we don't use AtlGetHexValue(), so it looks like I can compile with /J with reasonable confidence. Have a bounty!Bluh

© 2022 - 2024 — McMap. All rights reserved.