By Keshava GN


2015-12-03 09:46:32 8 Comments

I have seen the following macro definitions in a coding book.

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

There was no explanation there.

Please explain to me how these will work as TRUE and FALSE.

6 comments

@0605002 2015-12-03 09:50:19

It is equivalent to writing

#define TRUE 1
#define FALSE 0

What the expression '/'/'/' actually does is dividing the character / (whatever its numeric value is) by itself, so it becomes 1.

Similarly, the expression '-'-'-' subtracts the character - from itself and evaluates to 0.

It would be better to write

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

to avoid accidental change of values when used with other higher-precedence operators.

@Kerrek SB 2015-12-03 09:50:57

What's 2 * FALSE -- do two wrongs make a right?

@0605002 2015-12-03 09:51:34

LOL! That's why macros should be properly parenthesized.

@M.M 2015-12-03 09:52:43

Two wrongs make a hyphen apparently

@Derek 朕會功夫 2015-12-05 09:00:39

3 rights on a sphere and you end up in the same place

@Tim Long 2016-02-02 01:18:45

@KerrekSB No, but three lefts do :)

@anand 2015-12-22 08:48:19

It hilarious way for writing macros for True and False.

As many explanations have been provided / means a 1 byte number(as per ASCII) when divided by itself it give you 1 which will be treat as True and likewise - is again a byte number when subtracted the same value it give you 0 which will be interpreted as false

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

hence we can replace / or - with any char we like, for example:

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

Will keep the same meaning as the original expression.

@ouah 2015-12-15 17:42:25

Jay already answered why the values of these expressions are 0 and 1.

For history sake, these expressions '/'/'/' and '-'-'-' come from one of the entries of 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);}

(Link to the program here, there is a hint of what this program does in the IOCCC page above.)

Also if I remember correctly these expressions as obfuscated macros for TRUE and FALSE were also covered in "Obfuscated C and Other Mysteries" book by Don Libes (1993).

@BlackDwarf 2015-12-03 09:50:12

It's just another way of writing

#define TRUE 1
#define FALSE 0

The expression '/'/'/' will divide the char value of '/' by itself, which will give 1 as a result.

The expression '-'-'-' will substract the char value of '-' from itself, which will give 0 as a result.

Brackets around the whole define expressions are missing though, which can lead to errors in the code using these macros. Jay's answer adresses that pretty well.

An example of "real-life" scenario where forgetting the brackets can be harmful is the combined use of these macros with a C-style cast operator. If someone decides to cast these expressions to bool in C++ for instance:

#include <iostream>

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

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

Here's what we get:

True: 0
False: -44

So (bool) TRUE would actually evaluate to false, and (bool) FALSE would evaluate to true.

@Kit Fisto 2016-05-06 16:54:54

The example is a nice one :)

@Jay 2015-12-03 09:50:48

Let's see: '/' / '/' means the char literal /, divided by the char literal '/' itself. The result is one, which sounds reasonable for TRUE.

And '-' - '-' means the char literal '-', subtracted from itself. This is zero (FALSE).

There are two problems with this: first, it's not readable. Using 1 and 0 is absolutely better. Also, as TartanLlama and KerrekSB have pointed out, if you are ever going to use that definition, please do add parentheses around them so you won't have any surprises:

#include <stdio.h>

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

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

This will print the value of the char literal '-' (45 on my system).

With parentheses:

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

the program correctly prints zero, even though it doesn't make much sense to multiply a truth value by an integer, but it's just an example of the kind of unexpected bugs that could bite you if you don't parenthesize your macros.

@Luis Masuelli 2015-12-03 14:51:22

Damn I took a lot to understand it :s even thought it was a weird thing as glyphs... don't know xD

@Alpedar 2015-12-04 09:02:46

It actually make sense to multiply with truth value. For examle indentation*should_indent will result in either 0 or indentation based on whether should_indent without branching. (I guess that this is bad example, when working with text single branching does not matter, (I've seen this technique in shaders and in XPATH (both too different and i don't remeber exact form))

@Jay 2015-12-04 10:26:47

Alpedar -- but it doesn't conceptually and matehmatically make senso to do so -- in this case it would be clearer (and conceptually make sense) to use an if instead of multiplying TRUE by an integer.

@Michael Hampton 2015-12-04 17:09:18

Great explanation. Have a gold badge!

@Hagen von Eitzen 2015-12-05 09:43:59

Logical negation might be implemented as notx = TRUE- x; and works fine. Except that TRUE-FALSE is -44 (assuming ASCII)

@Marc Wittke 2016-02-02 01:59:31

As a frequent .net / web coder - this amplifies my strange feeling on C-guys as PWFs - "people without friends" :D

@Konstantin Yovkov 2016-02-02 08:36:53

Nice explanation. I've seen such defines on some programming contest platforms, like TopCoder, where at some point of a contest you're supposed to "hack" someone else's program. It's a good way to confuse people. :)

@Peter Cordes 2019-05-30 11:22:37

@MarcWittke: Well, people who abuse the C preprocessor with broken macros like these will soon be without friends. It's well known that simple text substitution of things that aren't rigorously guarded with parens can create extremely non-obvious breakage, which is why C++ introduces so many ways to do things without the C preprocessor, like templates and static const bool TRUE = true;. (Although this definition actually has a type of int, not bool.)

@Fabien 2015-12-03 09:50:50

Let's start with true. You can read it as '/' / '/', which means "character '/' divided by character '/'". Since each character, in C, is a numeric value (on one byte), it can be read as "the ASCII value of character '/' divided by the ASCII value of that same character", which means 1 (because, obviously, x/x is 1). Hence, TRUE is 1.

For FALSE, its the same reasoning: '-'-'-' reads '-' - '-', i.e "the ASCII value of '-' minus the ASCII value of '-'", which is 0. Hence, FALSE is 0.

This is a nasty way to state the obvious.

@Kerrek SB 2015-12-03 09:51:23

This has nothing to do with ASCII.

@Fabien 2015-12-03 10:01:29

@KerrekSB, in practice, yes, it does, unless you happen to develop on a very specific architecture, which is probably not relevant to OP's question.

@Keith Thompson 2015-12-03 16:24:58

@Fabien: It doesn't depend on ASCII. '/'/'/' is 1 for any valid character set, whether '/' == 47 (as it is in ASCII), or '/' == 97 (as it is in EBCDIC), or any other value.

@Paweł Załuski 2015-12-03 20:32:01

@KeithThompson Well, not for any character set - just the limited subset of those that do not map '/' == 0 ;) which ASCII (or EBCDIC for that matter) are good examples of...

@Keith Thompson 2015-12-03 20:44:41

@Pawel: A conforming C implementation cannot map '/' to 0. That value is reserved for the null character.

@Paweł Załuski 2015-12-03 21:54:34

@KeithThompson :) If we're talking about ISO C then true - it defines null character as the zero byte, but still - you argued any character set and nothing stops an arbitrary character set to designate null character as the visual glyph '/'

@Keith Thompson 2015-12-03 22:04:27

@Pawel: Sure, I could have been more explicit. But since the question is about C (and C++), that's what I meant by "any valid character set".

@Matheus208 2015-12-04 13:50:47

You are being pedantic.

@Zhora 2015-12-04 20:31:17

@Matheus208 If Pawel was being pedantic, then that's ('-'-'-') since his point was based on an unstated condition; describing Keith's remarks as pedantic might be more ('/'/'/') but I'd call them "clarifying" (and with the added smileys "pedantic" definitely seems '/'-'/' to me). It may be ('-'/'-') that the comments taken together can be called pedantic but, 1) isn't that somewhat obligatory in this field? 2) they made me think; and 3) I'm a bit clearer on some things than I was. And yes, I guess I'm being pedantic myself! (But I'm clearer about what "pedantic" means than I was! ;-)

@Keith Thompson 2015-12-09 00:32:12

@Matheus208: You say that like it's a bad thing.

@BalinKingOfMoria 2015-12-09 16:00:02

Wow. This is so wonderful. @zhora, kudos for discussing the definition of "pedantic." I give all of you my deepest congratulations for your inerrant toils to improve the accuracy of the Internet.

Related Questions

Sponsored Content

21 Answered Questions

[SOLVED] What is the "-->" operator in C++?

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

12 Answered Questions

[SOLVED] Which MySQL data type to use for storing boolean values

4 Answered Questions

[SOLVED] What does the C ??!??! operator do?

  • 2011-10-19 16:56:59
  • Peter Olson
  • 243574 View
  • 1837 Score
  • 4 Answer
  • Tags:   c operators trigraphs

1 Answered Questions

[SOLVED] The Definitive C Book Guide and List

  • 2009-02-18 18:32:02
  • lillq
  • 381251 View
  • 401 Score
  • 1 Answer
  • Tags:   c

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2151295 View
  • 4248 Score
  • 1 Answer
  • Tags:   c++ c++-faq

10 Answered Questions

4 Answered Questions

[SOLVED] Is the operation "false < true" well defined?

8 Answered Questions

[SOLVED] Why #define TRUE (1==1) in a C boolean macro instead of simply as 1?

  • 2013-06-09 13:22:23
  • user2468316
  • 20592 View
  • 158 Score
  • 8 Answer
  • Tags:   c precompiler

Sponsored Content