TRUE和FALSE宏的奇怪定义

时间:2015-12-03 09:46:32

标签: c++ c macros boolean obfuscation

我在编码书中看到了以下宏定义。

db.secondCollection.find({"firstCollectionField":{$exists:false}})

那里没有解释。

请向我解释这些内容如何作为#define TRUE '/'/'/' #define FALSE '-'-'-' TRUE

6 个答案:

答案 0 :(得分:374)

我们看到:'/' / '/'表示char文字/,除以char文字'/'本身。结果是一个,TRUE听起来合理。

'-' - '-'表示char文字'-',从中减去。这是零(FALSE)。

这有两个问题:第一,它不可读。使用10绝对会更好。另外,正如TartanLlama和KerrekSB所指出的那样,如果您打算使用该定义,请在它们周围添加括号,这样您就不会有任何意外:

#include <stdio.h>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
        printf ("%d\n", 2 * FALSE);
        return 0;
}

这将打印char文字'-'的值(我的系统上为45)。

括号:

#define TRUE  ('/'/'/')
#define FALSE ('-'-'-')

程序正确地打印零,即使将真值乘以整数没有多大意义,但它只是一个例子,如果你没有括起你的宏,可能会咬你的意外错误

答案 1 :(得分:87)

这只是另一种写作方式

#define TRUE 1
#define FALSE 0

表达式'/'/'/''/'的char值除以其自身,结果为1。

表达式'-'-'-'将从自身中减去'-'的char值,结果为0。

虽然缺少整个define表达式的括号,但这可能导致使用这些宏的代码出错。 Jay's answer很好地说明了这一点。

忘记括号可能有害的“真实”场景的一个例子是将这些宏与C风格的强制转换运算符结合使用。如果有人决定将这些表达式转换为C ++中的bool

#include <iostream>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
    std::cout << "True: " << (bool) TRUE << std::endl;
    std::cout << "False: " << (bool) FALSE << std::endl;
    return 0;
}

这是我们得到的:

True: 0
False: -44

因此,(bool) TRUE实际上会评估为false,而(bool) FALSE会评估为true

答案 2 :(得分:44)

相当于写作

#define TRUE 1
#define FALSE 0

表达式'/'/'/'实际上做的是将字符/(无论其数值是什么)除以它自己,因此它变为1

同样,表达式'-'-'-'从自身中减去字符-并计算为0

最好写

#define TRUE ('/'/'/')
#define FALSE ('-'-'-')

以避免在与其他更高优先级的运算符一起使用时意外更改值。

答案 3 :(得分:32)

Jay已经回答了为什么这些表达式的值为01

为了历史起见,这些表达式'/'/'/''-'-'-'来自1st International Obfuscated C Code Contest in 1984的其中一个条目:

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

(链接到程序here,这个程序在上面的IOCCC页面中有一些提示。)

此外,如果我没记错,这些表达式作为TRUEFALSE的混淆宏也包含在Don Libes(1993)的"Obfuscated C and Other Mysteries"书中。

答案 4 :(得分:7)

TrueFalse编写宏的热闹方式。

提供了很多解释/表示一个1字节的数字(按照ASCII),当它除以它时,它会给你1,它将被视为True,同样- 1}}再次是一个字节数,减去它给你0的相同值,它将被解释为false

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

因此我们可以用我们喜欢的任何字符替换/-,例如:

#define TRUE  '!'/'!'
#define FALSE 'o'-'o'

与原始表达保持相同的含义。

答案 5 :(得分:6)

让我们从真实开始吧。您可以将其读作'/' / '/',这意味着“字符'/'除以字符'/'”。由于C中的每个字符都是一个数值(在一个字节上),因此可以将其读作“字符的ASCII值'/'除以相同字符的ASCII值”,这意味着1(因为很明显, x / x是1)。因此,TRUE为1。

对于FALSE,其原因相同:'-'-'-'读取'-' - '-',即“ - '的ASCII值减去' - '的ASCII值,即0。因此,FALSE为0。

这是陈述显而易见的一种令人讨厌的方式。