1

This question has no practical use! I've asked this only because I'm curious!

There is a way in C++ to falsify true as false by writing somewhere #define true false, and then everywhere true in code will considered as false. But I'm seeking for a way to falsify true as false and false as true at the same time:

#define true false
#define false true

This doesn't works, and trying to "save" original true also doesn't:

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

Do you know any way to do that?

jxh
  • 69,070
  • 8
  • 110
  • 193
Gordem
  • 115
  • 9
  • 2
    This is Undefined Behavior. "It doesn't work" is to be expected. – MSalters Jul 14 '20 at 07:59
  • Thanks @MSalters. Apart from my answer (of course ;-)) this is the only sane comment or answer on this page. – Bathsheba Jul 14 '20 at 08:15
  • @Bathsheba Both my and the accepted answer *also* point out that this is undefined and pointless. – Konrad Rudolph Jul 14 '20 at 09:18
  • Redefining any keywords from the language is not allowed. It makes the program basically invalid. – Martin York Jul 14 '20 at 18:13
  • See Section: `17.6.4.3 Reserved names` Paragraph 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.` See section `2.11 Keywords` for keywords which includes true and false. – Martin York Jul 14 '20 at 18:26
  • @jxh The standard is clear on the issue. See the section quoted above. The discussion in stackoverflow you link is not relevant to this discussion and talking about the wrong section of the standard. I have mentioned the correct part of the standard and its clear that this is illegal there is no interpretation. – Martin York Jul 14 '20 at 19:47
  • @MartinYork: You are citing a section that is still governed by *[constraints]*, and *[constraints.overview]* says it only applies when using the standard library. – jxh Jul 14 '20 at 19:57

4 Answers4

3

Perhaps something like this?

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

Regarding undefined behavior:

Those that say it is undefined are probably referring to the answer to this question: Is it legal to redefine a C++ keyword?

However, if you do not use the standard C++ library, the cited restriction does not apply (kudos to Bathsheba and Martin York).

16.5.4.1 [constraints.overview]
Subclause 16.5.4 describes restrictions on C++ programs that use the facilities of the C++ standard library.
...
16.5.4.3.2 [macro.names] ...
A translation unit shall not #define or #undef names lexically identical to keywords, ...
C++ 2020 draft

jxh
  • 69,070
  • 8
  • 110
  • 193
  • 1
    It's pretty but unfortunately the behaviour is undefined. – Bathsheba Jul 14 '20 at 08:14
  • Updated to the latest version of the standard so I get it correct (my copy was a few versions old). http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861.pdf See Section `16.5.4.3.2 Macro names`: Paragraph 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).` – Martin York Jul 14 '20 at 20:09
  • @jhx: Paragraph 1 explicitly deals with including header files from the standard library. Paragraph 2 puts no restrictions and applies all the time. Just linking against the standard library invokes `16.5.4.1` does not need to include header files. You need to link against the standard library to make the application run (unless you are a small subset of embedded systems). – Martin York Jul 14 '20 at 20:23
  • @MartinYork: Just to make sure these objections and clarifications have context. You are citing a section that is still governed by *16.5.4 [constraints]*, and *16.5.4.1 [constraints.overview]* says it only applies when using the standard library. This has been clarified in the answer. Thanks for the help. – jxh Jul 14 '20 at 21:16
2

The behaviour on attempting to #define a C++ keyword is undefined. Don't do it!

It's not quite so pretty, but

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

is probably the best you can do.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

This obviously has no practical use whatsoever and is not valid C++, but the following does the trick:

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

#define true fake_true
#define false fake_false

Simply using numeric literals (e.g. 1 and 0) might appear simpler but will cause different semantics in situations where the type matters (e.g. overload resolution).

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
1

use constexpr variables rather changing the behavior of true and false.

static constexpr bool TRUE = false;
static constexpr bool FALSE = true;
Const
  • 1,306
  • 1
  • 10
  • 26
  • 2
    Careful. The macros `TRUE` and `FALSE` are defined in a lot of C header files that can be included in by C++ header files. – Martin York Jul 14 '20 at 19:10