TRUEおよびFALSEマクロの奇妙な定義


300

コーディングブックで次のマクロ定義を見ました。

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

そこには説明がありませんでした。

これらのように動作するか私に説明してくださいTRUEFALSE


63
TRUEを1、FALSEを0と定義するのはおもしろい方法だと思います
BlackDwarf

160
これは、これらの式を括弧で囲まないひどい考えです。私はそれはひどいアイデアだ意味を持つ彼らが、あなただけのデバッグの長い夜を求めていなくて。
TartanLlama

70
あなたが参照しているコーディングブックを教えていただけますか?
artm

47
本に、これが悪いコードまたは意図的に不明瞭なコードの例として含まれていることを望みます。
Jon Hanna

31
@ダニエル:もう1つのアイデアは、rand()%2をMAYBEをrand()%2として定義することです。
Kaiserludi 2015

回答:


380

見てみましょう:'/' / '/'手段charリテラル/で割った、char文字通り'/'自分自身を。結果は1ですTRUE

そして、それ自体から差し引かれ'-' - '-'charリテラルを意味'-'します。これはゼロ(FALSE)です。

これには2つの問題があります。1つ目は、判読できないことです。とを使用する1と、0絶対に優れています。また、TartanLlamaとKerrekSBが指摘したように、その定義を使用する予定がある場合は、驚きがないように括弧をかっこで囲んでください。

#include <stdio.h>

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

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

これはcharリテラルの値を出力します'-'(私のシステムでは45)。

括弧付き:

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

真理値を整数で乗算することはあまり意味がありませんが、プログラムは正しく0を出力しますが、これは、マクロを括弧で囲まない場合に噛み付く可能性のある予期しないバグの例にすぎません。


6
くそーそれを理解するのにたくさんかかりました:sそれはグリフとしては奇妙なものだとさえ思っていました... xDを知らない
Luis Masuelli

8
実際、真理値と乗算することには意味があります。たとえば、インデント* should_indentは、分岐なしのshould_indentに基づいて、0またはインデントになります。(これは悪い例だと思います。テキストの単一分岐を操作する場合は問題になりません(この手法はシェーダーとXPATHで見ました(どちらも違いすぎ、正確な形式を覚えていません))
Alpedar

2
Alpedar-ただし、概念的にも数学的にもそうではありません-この場合、整数ifを乗算する代わりにを使用する方が明確です(概念的には意味があります)TRUE
Jay

4
素晴らしい説明。ゴールドバッジを獲得しましょう。
マイケルハンプトン

2
論理否定はとして実装されnotx = TRUE- x;、正常に機能します。それ以外TRUE-FALSEは-44(ASCIIを想定)
ハーゲンフォンアイツェン

89

それはただの書き方のひとつです

#define TRUE 1
#define FALSE 0

'/'/'/''/'それ自体でchar値を除算し、結果として1を返します。

'-'-'-''-'それ自体からchar値を減算し、結果として0 を返します。

defineただし、式全体を囲む括弧が欠落しているため、これらのマクロを使用するコードでエラーが発生する可能性があります。ジェイの答えはそれをかなりうまく対処しています。

ブラケットを忘れると有害になる可能性がある「実際の」シナリオの例は、これらのマクロをCスタイルのキャスト演算子と組み合わせて使用​​することです。たとえばbool、C ++でこれらの式をキャストすることにした場合:

#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ます。


4
例は素晴らしいものです:)
キットフィスト

44

書くことと同じ

#define TRUE 1
#define FALSE 0

式が'/'/'/'実際に行うことは、文字/(その数値が何であれ)をそれ自体で除算することなので、になり1ます。

同様に、式はそれ自体から'-'-'-'文字-を減算し、に評価され0ます。

書くほうがいい

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

他の優先順位の高い演算子と併用した場合に値が誤って変更されるのを防ぐため。


5
笑!そのため、マクロは適切に括弧で囲む必要があります。
0605002

球体に対する3つの権利と同じ場所に移動
デレク朕會會夫

@KerrekSBいいえ、ただし3つの左はそうします:)
Tim Long

33

ジェイは、すでにこれらの式の値は、なぜ答えた01

歴史のために、これらの式'/'/'/''-'-'-'のエントリのいずれかから来る1984年の第1回国際難読Cコードコンテスト

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);}

ここにプログラムへのリンクがあります。このプログラムが何をするかのヒントが上のIOCCCページにあります。)

また、私はのために難読化されたマクロとして正しくこれらの表現を覚えていればTRUEFALSEもに覆われていた「難読Cおよびその他の謎」ドン・リブス(1993)による著書。


7

この陽気のためのマクロを記述するための方法TrueFalse

多くの説明が提供されているように/(ASCIIの通り)1つのバイトの数を意味し、それ自体で割ったとき、それはあなたを与える1ように治療されるTrueと同様に -、それはあなたを与える同じ値を減算するとき再びバイト数である0と解釈されますfalse

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

したがって、我々は交換することができます/または-たとえば、私たちが好きな文字で:

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

元の表現と同じ意味を保ちます。


6

真から始めましょう。'/' / '/'これは、「文字 '/'を文字 '/'で割ったもの」と読むことができます。Cの各文字は数値(1バイト)であるため、「文字 '/'のASCII値を同じ文字のASCII値で割ったもの」として読み取ることができます。これは、1を意味します(明らかに、 x / xは1)です。したがって、TRUE1です。

以下のためにFALSEその同じ論法、:'-'-'-'読み込み'-' - '-'、すなわち「『 - 』マイナスのASCII値『 - 』のASCII値」、したがって0で、FALSE0です。

これは明白なことを述べるための厄介な方法です。


7
これはASCIIとは関係ありません。
Kerrek SB、2015

6
@ファビエン:ASCIIに依存しない。'/'/'/'図1は、のためにある任意のかどうか、有効な文字セット'/' == 47(それがASCIIであるとして)、または'/' == 97(それがEBCDICであるとして)、または他の値。
キース・トンプソン

4
@Pawel:A準拠のC実装は、マップすることはできません'/'0。その値はヌル文字用に予約されています。
キース・トンプソン

2
あなたは独断的です。
Matheus208

3
@ Matheus208 Pawelが奇抜であった場合、それは( '-'-'-')です。これは、彼の主張が述べられていない状態に基づいているためです。キースの発言を教育的であると説明することはもっと( '/' / '/')かもしれませんが、私はそれらを「明確化」と呼びます(そして、追加されたスマイリーで「教育的」は間違いなく '/'-'/'に思えます)。( '-' / '-')は、一緒に取られたコメントを一歩一歩と呼ぶことができるかもしれませんが、1)このフィールドではそれほど義務的ではありませんか?2)彼らは私に考えさせました。および3)いくつかのことについては、以前よりも少し明確です。そして、はい、私は自分自身を理解していると思います!(しかし、私は「ペダンティック」の意味が私よりもはっきりしています!;-)
Zhora
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.