【问题标题】:Is it safe to mix UNICODE and non-UNICODE translation units?混合 UNICODE 和非 UNICODE 翻译单元是否安全?
【发布时间】:2021-11-30 20:13:50
【问题描述】:

我正在集成一个需要定义 _UNICODEUNICODE 的库;我现在无法在我的项目中全局设置这些定义,所以我想知道我是否可以安全地只使用这些定义构建库代码。

我担心 ODR 违规,但据我了解,这些定义仅影响 Windows 和 C 运行时标头中的 定义,因此我预计不会出现 ODR 违规(只要我的翻译单元之间共享的自己的标头不依赖于UNICODE),但这真的是一种保证吗?

混合使用和不使用 UNICODE/_UNICODE 构建的翻译单元是否安全?

换句话说,将这两个文件编译成同一个二进制文件是否安全:

// 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

【问题讨论】:

  • 有关信息,库维护人员正在重构他们的代码,使其独立于 UNICODE 宏,但这可能需要一些时间(无论如何这个问题仍然很有趣)。
  • 对我来说,问题浓缩为:_UNICODEUNICODE 对库的标题有什么影响吗?因为,这是编译器在其他代码使用库时所考虑的。
  • 如果有一个带有_TEXT()/TCHAR/... 的内联函数,一个定义了预处理器,一个没有定义(即使未使用函数),那么您就会违反 ODR。所以“安全吗?”否。您目前是否存在 ODR 违规行为?不确定,也许,也许不是。 Microsoft 是否可以更改 &lt;tchar.h&gt; 或其他 Windows 标头以可能会导致您的代码违反 ODR?是的。他们会这样做吗?也许,也许不是。目前 tchar.h 只有 #define/typedef 一些别名。所以它本身不会违反 ODR。
  • “有两个定义不同的 typedef 违反 ODR” 我从 ODRtypedef 了解到的情况并非如此。 (如果在 inline 函数中使用它可能会导致 UB)。
  • 看起来有允许这样做的意图,但仍然没有记录;在某些情况下,SDK 可能存在导致此意图失败的错误

标签: c++ visual-c++ unicode one-definition-rule


【解决方案1】:

如果在不同的翻译单元中有一个带有_TEXT()/TCHAR/... 的内联函数,一个定义了预处理器,一个没有定义(即使没有使用函数),那么你得到ODR-violation .

“安全吗?”

没有。

您目前是否存在 ODR 违规行为?

不确定,也许,也许不是。

目前tchar.h 只有#define/typedef 一些别名。所以它本身不会违反 ODR。

Microsoft 是否可以更改 或其他 Windows 标头以可能会导致您的代码违反 ODR?

是的。

他们会这样做吗?

也许,也许不是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多