Home > front end >  Is it safe to mix UNICODE and non-UNICODE translation units?
Is it safe to mix UNICODE and non-UNICODE translation units?

Time:10-13

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.

  • Related