【问题标题】:Falsify true ↔ false伪造真 ↔ 假
【发布时间】:2020-11-03 12:11:44
【问题描述】:

这个问题没有实际用处!我问这个只是因为我很好奇!

在 C++ 中有一种方法可以通过在某处写入 #define true false 来将 true 伪造为 false,然后代码中的任何地方 true 都将被视为 false。但我正在寻找一种同时将true 伪造为falsefalsetrue 的方法:

#define true false
#define false true

这不起作用,尝试“保存”原始 true 也不起作用:

#define temptrue true
#define true false
#define false temptrue

你知道有什么办法吗?

【问题讨论】:

  • 这是未定义的行为。 “它不起作用”是意料之中的。
  • 感谢@MSalters。除了我的回答(当然 ;-))这是此页面上唯一理智的评论或回答。
  • @Bathsheba 我和接受的答案 指出这是未定义且毫无意义的。
  • 不允许从语言中重新定义任何关键字。使程序基本无效。
  • 参见章节:17.6.4.3 Reserved names 第 2 段 A translation unit shall not #define or #undef names lexically identical to **keywords**, to the identifiers listed in Table 2, or to the attribute-tokens described in 7.6. 参见章节 2.11 Keywords 了解包含真假的关键字。

标签: c++ c-preprocessor


【解决方案1】:

也许是这样的?

#define false static_cast<bool>(1)
#define true  static_cast<bool>(0)

关于未定义的行为:

那些说它未定义的人可能指的是这个问题的答案:Is it legal to redefine a C++ keyword?

但是,如果您不使用标准 C++ 库,则引用的限制不适用(感谢 Bathsheba 和 Martin York)。

16.5.4.1 [constraints.overview]
子条款 16.5.4 描述了对使用 C++ 标准库设施的 C++ 程序的限制。
...
16.5.4.3.2 [macro.names] ...
翻译单元不得#define#undef 名称在词法上与关键字相同,...
C++ 2020 draft

【讨论】:

  • 很漂亮,但不幸的是行为未定义。
  • 更新到最新版本的标准,所以我得到了正确的(我的副本是旧的几个版本)。 open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861.pdf 参见16.5.4.3.2 Macro names 部分:第 2 段 A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 4, or to the attribute-tokens described in 9.12, except that the names likely and unlikely may be defined as function-like macros (15.6).
  • @jhx:第 1 段明确涉及包含标准库中的头文件。第 2 款没有任何限制,并且始终适用。仅链接标准库调用16.5.4.1 不需要包含头文件。您需要链接标准库以使应用程序运行(除非您是嵌入式系统的一小部分)。
  • @MartinYork:只是为了确保这些反对意见和澄清有上下文。您引用的部分仍受 16.5.4 [constraints] 管辖,而 16.5.4.1 [constraints.overview] 表示它仅在使用标准库时适用。这已在答案中阐明。感谢您的帮助。
【解决方案2】:

尝试#define C++ 关键字的行为未定义。不要这样做!

不是很漂亮,但是

static constexpr bool true_ = false;
static constexpr bool false_ = true;

可能是你能做的最好的了。

【讨论】:

  • @KonradRudolph:你赢了,下次我在剑桥的时候我会请你吃午饭。谢谢。
  • 午餐需要等待,尤其是因为我目前被困在伦敦(仍在 Cambs 工作,但去年搬到了卡姆登)。
  • 这是唯一合法有效的建议。
【解决方案3】:

这显然没有任何实际用途,也不是有效的 C++,但以下方法可以解决问题:

static constexpr auto fake_true = false;
static constexpr auto fake_false = true;

#define true fake_true
#define false fake_false

仅使用数字文字(例如 1 和 0)可能看起来更简单,但在类型很重要的情况下会导致不同的语义(例如重载决议)。

【讨论】:

    【解决方案4】:

    使用constexpr 变量而不是更改truefalse 的行为。

    static constexpr bool TRUE = false;
    static constexpr bool FALSE = true;
    

    【讨论】:

    • 小心。宏TRUEFALSE定义在很多C头文件中,可以被C++头文件包含。
    猜你喜欢
    • 2017-01-30
    • 2022-07-05
    • 2018-03-13
    • 2015-03-30
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2012-07-08
    • 2014-10-25
    相关资源
    最近更新 更多