Logical OR in C – Why 5 || 0 Prints 1, Not 5

What does 5 || 0 print — 5, or 1? If you’re coming from Python or JavaScript, where or hands back one of the operands, C will surprise you: logical OR in C always yields exactly 0 or 1, never the operand itself. That’s the trap in this question from our C Programming Quiz App.

The Quiz Question

printf("%d", 5 || 0);

What is printed by this code?

  1. 5
  2. 0
  3. 1
  4. Compile error

The Correct Answer: 1

The C standard defines || to yield an int: 1 if either operand is nonzero, 0 otherwise. 5 is nonzero — “true” in C’s book — so the whole expression is 1. Verified on gcc 13.3 and Apple clang 21:

$ gcc -Wall -Wextra or.c && ./a.out
1

C’s rule of truthiness is beautifully simple: 0 is false, everything else is true — but the logical operators normalize their verdict down to a clean 1 or 0. Even 5 || 3, where both sides are true, still prints 1.

Why Each Wrong Answer Is Wrong

Why not 5?

Two ways to arrive at 5, both instructive. First, thinking of Python/JavaScript semantics, where 5 or 0 returns 5 — C doesn’t do that. Second, confusing logical OR with bitwise OR — and that one we can demonstrate:

printf("%d\n", 5 || 0);   /* 1 — logical: is either true?     */
printf("%d\n", 5 | 0);    /* 5 — bitwise: merge the bits      */

One pipe merges bit patterns (101 | 000 = 101 = 5); two pipes deliver a true/false verdict.

Why not 0?

0 would require both operands to be zero. Only 0 || 0 yields 0 — one nonzero side is enough for a 1.

Why not “Compile error”?

Mixing “boolean-looking” and integer operands is completely ordinary C — the language had no separate boolean type at all until C99’s _Bool, and logical operators are defined on scalars. Both compilers accept the quiz line silently. (Amusingly, writing constants on both sides of || can draw a clang warning — -Wconstant-logical-operand — suggesting you probably meant |. A warning, not an error, and only for constants.)

The Other Superpower: Short-Circuiting

|| doesn’t just normalize to 0/1 — it also evaluates lazily. If the left operand is nonzero, the right operand is never evaluated at all; the answer is already known to be 1. That’s what makes guard idioms safe:

if (p == NULL || p->count == 0)   /* deref only happens if p != NULL */

The flip side: when the left side is 0, the right side must run — including any side effects or, worse, any division by zero lurking there. That exact trap is quiz question #127, covered in depth in our short-circuit evaluation post. There’s also a guaranteed sequence point after the left operand — one of the few places C promises evaluation order (see sequence points).

Frequently Asked Questions

Does || return one of its operands in C?

No. Unlike Python’s or or JavaScript’s ||, C’s logical OR always yields an int that is exactly 0 or 1. 5 || 0 is 1, not 5.

What is the difference between || and | in C?

|| is logical: it tests truthiness, yields 0 or 1, and short-circuits. | is bitwise: it merges the bit patterns of both operands (5 | 0 = 5) and always evaluates both sides.

Does 5 || 3 print 2 because both are true?

No — logical operators don’t count or add. Any combination with at least one nonzero operand yields exactly 1.

Related Reading

Recommended Books

This question is #10 in the C Programming Quiz App — 155 questions with explanations covering operators, pointers, memory, and more.
Download on Google Play →

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>