I'm integrating a library which requires _UNICODE
and UNICODE
to be defined; I can't set these definitions globally on my project for now, so I was wondering if I can safely build only the library code with these definitions.
I'm worried about ODR violations, but as far as I understand these definitions only impact macro definitions in the Windows and C runtime headers, so I would expect no ODR violations (as long as my own headers shared between translation units don't depend on UNICODE
), but is it really a guarantee?
Is it safe to mix translation units built with and without UNICODE
/_UNICODE
?
In other words, is it safe to compile these two files into the same binary:
// a.cpp
#define _UNICODE
#define UNICODE
#include <tchar.h>
// maybe other windows header inclusion
// some code
// b.cpp
//#define _UNICODE
//#define UNICODE
#include <tchar.h>
// maybe other windows header inclusion
// some other code
CodePudding user response:
If there is one inline function with _TEXT()
/TCHAR
/... in different translation unit, one with preprocessor defined and one not (even if function is not used), then you got ODR-violation.
"is it safe?"
No.
Do you have currently ODR violations?
Not sure, maybe, maybe not.
Currently that tchar.h only #define
/typedef
some aliases. so doesn't do ODR-violation by itself.
Can Microsoft change <tchar.h> or other windows headers in a way it might produce ODR violation for your code?
Yes.
Would they do it?
Maybe, maybe not.
CodePudding user response:
Consider an example where it really hurts:
class SomeClass
{
// ...
TCHAR path[MAX_PATH];
};
If two units see SomeClass
with different definitions of TCHAR
then it may easily cause silent stack or heap corruption
CodePudding user response:
You can mix UNICODE and non-UNICODE compiles when there are no typedef
, for example if tchar.h
is not included.
Otherwise UNICODE
will just determine the macro translation of SetWindowText
, and other APIs and macros. It is possible to combine Unicode and ANSI, but it's confusing.
Note that in a single function, it is valid to call both SetWindowTextA(hwnd, "ansi")
and SetWindowTextW(hwnd, L"unicode")
. You can compile the project as Unicode and use the ANSI APIs for optional interface.