Usage of NOT operator in #define directives in C programming - c

I have defined macros as below.
#define FALSE 0
#define TRUE (!FALSE)
What will be the data-type of TRUE and FALSE? What literal value does TRUE take after preprocessing? Is it compiler dependent? Why?

#define preprocessor directive (macros) are meant to do textual replacement. It will replace all occurrence of FALSE to 0 and TRUE to !0 that essentially gets evaluated to 1. So, the resultant data type will be same as 0 and 1. i.e., integer.
Regarding the usage of ! operator, it always produces a result of type int.
Quoting the C11 standard, chapter §6.5.3.3 (emphasis mine)
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. [...]

At the time of preprocessing, macros are replaced with text.
FALSE will be replace by 0, and TRUE will be replaced by 1.

Related

Why does "sizeof(a ? true : false)" give an output of four bytes?

I have a small piece of code about the sizeof operator with the ternary operator:
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a = true;
printf("%zu\n", sizeof(bool)); // Ok
printf("%zu\n", sizeof(a)); // Ok
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
return 0;
}
Output (GCC):
1
1
4 // Why 4?
But here,
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
the ternary operator returns boolean type and sizeof bool type is 1 byte in C.
Then why does sizeof(a ? true : false) give an output of four bytes?
It's because you have #include <stdbool.h>. That header defines macros true and false to be 1 and 0, so your statement looks like this:
printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?
sizeof(int) is 4 on your platform.
Here, ternary operator return boolean type,
OK, there's more to that!
In C, the result of this ternary operation is of type int. [notes below (1,2)]
Hence the result is the same as the expression sizeof(int), on your platform.
Note 1: Quoting C11, chapter §7.18, Boolean type and values <stdbool.h>
[....] The remaining three macros are suitable for use in #if preprocessing directives. They
are
true
which expands to the integer constant 1,
false
which expands to the integer constant 0, [....]
Note 2: For conditional operator, chapter §6.5.15, (emphasis mine)
The first operand is evaluated; there is a sequence point between its evaluation and the
evaluation of the second or third operand (whichever is evaluated). The second operand
is evaluated only if the first compares unequal to 0; the third operand is evaluated only if
the first compares equal to 0; the result is the value of the second or third operand
(whichever is evaluated), [...]
and
If both the second and third operands have arithmetic type, the result type that would be
determined by the usual arithmetic conversions, were they applied to those two operands,
is the type of the result. [....]
hence, the result will be of type integer and because of the value range, the constants are precisely of type int.
That said, a generic advice, int main() should better be int main (void) to be truly standard-conforming.
The ternary operator is a red herring.
printf("%zu\n", sizeof(true));
prints 4 (or whatever sizeof(int) is on your platform).
The following assumes that bool is a synonym for char or a similar type of size 1, and int is larger than char.
The reason why sizeof(true) != sizeof(bool) and sizeof(true) == sizeof(int) is simply because true is not an expression of type bool. It's an expression of type int. It is #defined as 1 in stdbool.h.
There are no rvalues of type bool in C at all. Every such rvalue is immediately promoted to int, even when used as an argument to sizeof. Edit: this paragraph is not true, arguments to sizeof don't get promoted to int. This doesn't affect any of the conclusions though.
Regarding the boolean type in C
A boolean type was introduced fairly late in the C language, in the year 1999. Before then, C did not have a boolean type but instead used int for all boolean expressions. Therefore all logical operators such as > == ! etc return an int of value 1 or 0.
It was custom for applications to use home-made types such as typedef enum { FALSE, TRUE } BOOL;, which also boils down to int-sized types.
C++ had a much better, and explicit boolean type, bool, which was no larger than 1 byte. While the boolean types or expressions in C would end up as 4 bytes in the worst case. Some manner of compatibility with C++ was introduced in C with the C99 standard. C then got a boolean type _Bool and also the header stdbool.h.
stdbool.h provides some compatibility with C++. This header defines the macro bool (same spelling as C++ keyword) that expands to _Bool, a type which is a small integer type, likely 1 byte large. Similarly, the header provides two macros true and false, same spelling as C++ keywords, but with backward compatibility to older C programs. Therefore true and false expand to 1 and 0 in C and their type is int. These macros are not actually of the boolean type like the corresponding C++ keywords would be.
Similarly, for backward compatibility purposes, logical operators in C still return an int to this day, even though C nowadays got a boolean type. While in C++, logical operators return a bool. Thus an expression such as sizeof(a == b) will give the size of an int in C, but the size of a bool in C++.
Regarding the conditional operator ?:
The conditional operator ?: is a weird operator with a couple of quirks. It is a common mistake to believe that it is 100% equivalent to if() { } else {}. Not quite.
There is a sequence point between the evaluation of the 1st and the 2nd or 3rd operand. The ?: operator is guaranteed to only evaluate either the 2nd or the 3rd operand, so it can't execute any side-effects of the operand that is not evaluated. Code like true? func1() : func2() will not execute func2(). So far, so good.
However, there is a special rule stating that the 2nd and 3rd operand must get implicitly type promoted and balanced against each other with the usual arithmetic conversions. (Implicit type promotion rules in C explained here). This means that the 2nd or 3rd operand will always be at least as large as an int.
So it doesn't matter that true and false happen to be of type int in C because the expression would always give at least the size of an int no matter.
Even if you would rewrite the expression to sizeof(a ? (bool)true : (bool)false) it would still return the size of an int !
This is because of implicit type promotion through the usual arithmetic conversions.
Quick answer:
sizeof(a ? true : false) evaluates to 4 because true and false are defined in <stdbool.h> as 1 and 0 respectively, so the expression expands to sizeof(a ? 1 : 0) which is an integer expression with type int, that occupies 4 bytes on your platform. For the same reason, sizeof(true) would also evaluate to 4 on your system.
Note however that:
sizeof(a ? a : a) also evaluates to 4 because the ternary operator performs the integer promotions on its second and third operands if these are integer expressions. The same of course happens for sizeof(a ? true : false) and sizeof(a ? (bool)true : (bool)false), but casting the whole expression as bool behaves as expected: sizeof((bool)(a ? true : false)) -> 1.
also note that comparison operators evaluate to boolean values 1 or 0, but have int type: sizeof(a == a) -> 4.
The only operators that keep the boolean nature of a would be:
the comma operator: both sizeof(a, a) and sizeof(true, a) evaluate to 1 at compile time.
the assignment operators: both sizeof(a = a) and sizeof(a = true) have a value of 1.
the increment operators: sizeof(a++) -> 1
Finally, all of the above applies to C only: C++ has different semantics regarding the bool type, boolean values true and false, comparison operators and the ternary operator: all of these sizeof() expressions evaluate to 1 in C++.
Here is a snippet from which is what included in the source
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#else /* __cplusplus */
There macros true and false are declared as 1 and 0 respectively.
however in this case the type is the type of the literal constants. Both 0 and 1 are integer constants that fit in an int, so their type is int.
and the sizeof(int) in your case is 4.
There is no boolean datatype in C, instead logical expressions evaluate to integer values 1 when true otherwise 0.
Conditional expressions like if, for, while, or c ? a : b expect an integer, if the number is non-zero it's considered true except for some special cases, here's a recursive sum function in which the ternary-operator will evaluate true until n reach 0.
int sum (int n) { return n ? n+sum(n-1) : n ;
It can also be used to NULL check a pointer, here's a recursive function that print the content of a Singly-Linked-List.
void print(sll * n){ printf("%d -> ",n->val); if(n->next)print(n->next); }

Return value of a boolean expression in C

For reasons that are not worth mentioning, I want to know if there's a standard defined value for boolean expressions. E.g.
int foo () {
return (bar > 5);
}
The context is that I'm concerned that our team defined TRUE as something different than 1, and I'm concerned that someone may do:
if (foo() == TRUE) { /* do stuff */ }
I know that the best option would be to simply do
if (foo())
but you never know.
Is there a defined standard value for boolean expressions or is it up to the compiler? If there is, is the standard value something included in C99? what about C89?
An operator such as ==, !=, &&, and || that results in a boolean value will evaluate to 1 of the expression is true and 0 if the expression is false. The type of this expressing is int.
So if the TRUE macro is not defined as 1, a comparison such as the above will fail.
When an expression is evaluated in a boolean context, 0 evaluates to false and non-zero evaluates to true. So to be safe, TRUE should be defined as:
#define TRUE (!0)
As was mentioned in the comments, if your compiler is C99 compliant, you can #include <stdbool.h> and use true and false.
According to C99:
6.5.3.3 (Unary arithmetic operators)
The result of the logical negation operator ! is 0 if the
value of its operand compares unequal to 0, 1 if the value of its
operand compares equal to 0. The result has type int. The
expression !E is equivalent to (0==E).
6.5.8 (Relational operators)
Each of the operators < (less than), > (greater than), <=
(less than or equal to), and >= (greater than or equal to)
shall yield 1 if the specified relation is true and 0 if it is false.
The result has type int.
6.5.9 (Equality operators)
The == (equal to) and != (not equal to) operators are
analogous to the relational operators except for their lower
precedence. Each of the operators yields 1 if the specified
relation is true and 0 if it is false. The result has type
int.
6.5.13 (Logical AND operator)
The && operator shall yield 1 if both of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
6.5.14 (Logical OR operator)
The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
The C programming language does not define Boolean value. Traditionally, the C programming language uses integer types to represent boolean data types.
Boolean values in C:
0 = false`
Any other value = true`
Usually people will use 1 for true.
C99 introduced the_Bool data type that is not available in other C derivates.See wikipedia link here. Additionally, a new header stdbool.h has been added for compatibility reasons. This header allows programmers to use boolean types in the same way, as in C++ language.
To use bool in C, we can use enum as below.
enum bool {
false, true
};
bool value;
value = bool(0); // False
value = bool(1); // True
if(value == false)
printf("Value is false");
else
printf("Value is true");
Also, related Stack overflow question
Is bool a native C type?

Does the C standard explicitly indicate truth value as 0 or 1?

We know that any numbers that are not equal to 0 are viewed as true in C, so we can write:
int a = 16;
while (a--)
printf("%d\n", a); // prints numbers from 15 to 0
However, I was wondering whether true / false are defined as 1/0 in C, so I tried the code below:
printf("True = %d, False = %d\n", (0 == 0), (0 != 0)); // prints: True = 1, False = 0
Does C standard explicitly indicate the truth values of true and false as 1 and 0 respectively?
Does the C standard explicitly indicate the truth values of true and false as 0 and 1 respectively?
The C standard defines true and false as macros in stdbool.h which expand to 1 and 0 respectively.
C11-§7.18:
The remaining three macros are suitable for use in #if preprocessing directives. They are
true
which expands to the integer constant 1,
false
which expands to the integer constant 0 [...]
For the operators == and != , standard says
C11-§6.5.9/3:
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
It is not explicitly indicated in C11. All language-level operations will return 1 as truthy (and accept any nonzero including NaN as true).
If you concern about _Bool, then true must be 1 because the standard only require it to hold 0 and 1. (§6.2.5/2).
Also in <stdbool.h> the macro true expands to 1 (§7.18/3)
==, !=, <, >, <= and >= return 0 or 1 (§6.5.8/6, §6.5.9/3).
!, && and || return 0 or 1 (§6.5.3.3/5, §6.5.13/3, §6.5.14/3)
defined expands to 0 or 1 (§6.10.1/1)
But all standard library functions e.g. islower just say "nonzero" for truthy (e.g. §7.4.1/1, §7.17.5.1/3, §7.30.2.1/1, §7.30.2.2.1/4).
§6.2.5/2: An object declared as type _Bool is large enough to store the values 0 and 1.
§6.5.5.3/5: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. …
§6.5.8/6: Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.107) …
§6.5.9/3: The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. …
§6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; …
§6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; …
§6.10.1/1: … it may contain unary operator expressions of the form — defined identifier — or — defined ( identifier ) — which evaluate to 1 if …
§7.4.1 (Character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.18/3: The remaining three macros are suitable for use in #if preprocessing directives. They are — true — which expands to the integer constant 1, …
§7.17.5.1/3: The atomic_is_lock_free generic function returns nonzero (true) if and only if the object’s operations are lock-free. …
§7.30.2.1 (Wide character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.30.2.2.1/4: The iswctype function returns nonzero (true) if and only if …
There are two areas of the standard you need to be aware with when dealing with Boolean values (by which I mean true/false values rather than the specific C bool/_Bool type) in C.
The first has to do with the result of expressions and can be found in various portions of C11 6.5 Expressions (relational and equality operators, for example) . The bottom line is that, whenever a Boolean value is generated by an expression, it ...
... yields 1 if the specified relation is true and 0 if it is false. The result has type int.
So, yes, the result of any Boolean-generating expression will be one for true, or zero for false. This matches what you will find in stdbool.h where the standard macros true and false are defined the same way.
Keep in mind however that, following the robustness principle of "be conservative in what you send, liberal in what you accept", the interpretation of integers in the Boolean context is somewhat more relaxed.
Again, from various parts of 6.5, you'll see language like:
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
From that (and other parts), it's obvious that zero is considered false and any other value is true.
As an aside, the language specifying what value are used for Boolean generation and interpretation also appear back in C99 and C89 so they've been around for quite some time. Even K&R (ANSI-C second edition and the first edition) specified that, with text segments such as:
Relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true, and 0 if false.
In the test part of if, while, for, etc, "true" just means "non-zero".
The && operator ... returns 1 if both its operands compare unequal to zero, 0 otherwise.
The || operator ... returns 1 if either its operands compare unequal to zero, and 0 otherwise.
The macros in stdbool.h appear back in C99 as well, but not in C89 or K&R since that header file did not exist at that point.
You are mixing up a lot of different things: control statements, operators and boolean types. Each have their own rules.
Control statements work like for example the if statement, C11 6.4.8.1:
In both forms, the first substatement is executed if the expression
compares unequal to 0.
while, for etc have the same rule. This has nothing to do with "true" or "false".
As for operators that are supposedly yielding a boolean result, they are actually yielding an int with value 1 or 0. For example the equality operators, C11 6.5.9:
Each of the operators yields 1 if the specified relation is true and 0
if it is false
All of the above is because C did not have a boolean type until the year 1999, and even when it did get one, the above rules weren't changed. So unlike most other programming languages where statements and operators yield a boolean type (like C++ and Java), they just yield an int, with a value zero or not zero. For example, sizeof(1==1) will give 4 in C but 1 in C++.
The actual boolean type in C is named _Bool and requires a modern compiler. The header stdbool.h defines macros bool, true and false, that expand to _Bool, 1 and 0 respectively (for compatibility with C++).
It is however considered good programming practice to treat control statements and operators as if they actually required/yielded a boolean type. Certain coding standards like MISRA-C recommend such practice. That is:
if(ptr == NULL) instead of if(ptr).
if((data & mask) != 0) instead of if(data & mask).
The aim of such style is to increase type safety with the aid of static analysis tools, which in turn reduces bugs. Arguably, this style is only meaningful if you do use static analysers. Though in some cases it leads to more readable, self-documenting code, for example
if(c == '\0')
Good, the intent is clear, the code is self-documenting.
versus
if(c)
Bad. Could mean anything, and we have to go look for the type of c to understand the code. Is it an integer, a pointer or a character?
I've programmed in many languages. I've seen true be 1 or -1 depending on the language. The logic behind true being 1 was that a bit was either a 0 or 1. The logic behind true being -1 was that the ! operator was a one's complement. It changed all the 1's to 0's and all the 0's to 1's in an int. So, for an int, !0 = -1 and !(-1) = 0. This has tripped me up enough that I don't compare something to be == true, but instead compare it to be != false. That way, my programming style works in every language. So my answer is to not worry about it, but program so that your code works correctly either way.
This answer needs to be looked at a bit more closely.
The actual definition in C++ is that anything not 0 is treated as true. Why is this relevant? Because C++ doesn't know what an integer is by how we think about it--we create that meaning, all it holds is the shell and rules for what that means. It knows what bits are though, that which make up an integer.
1 as an integer is loosely represented in bits, say an 8-bit signed int as 0000 0001. Many times what we see visually is a bit of a lie, -1 is a much more common way to represent it because of the signed nature of 'integer'. 1 really can't mean true proper, why? Because it's NOT operation is 1111 1110. That's a really major issue for a boolean. When we talk about a boolean, it's just 1 bit--it's really simple, 0 is false and 1 is true. All the logic operations hold as trivial. This is why '-1' should be designated as 'true' for integers (signed). 1111 1111 NOT'ed becomes 0000 0000---the logic holds and we're good. Unsigned ints is a little bit tricky and were a lot more commonly used in the past--where 1 means true because it's easy to imply the logic that 'anything not 0 is true'.
That's the explanation. I say the accepted answer here is wrong--there is no clear definition in the C/C++ definition. A boolean is a boolean, you can treat an integer as a boolean, but the fact the output is an integer says nothing about the operation actually being done is bitwise.
It happened because of the Relational Operators in your printf statement.
Operator == and operator !=
Since (0 == 0) holds true so, it gives a value 1
whereas, (0 != 0) doesn't hold true so, gives a value 0 .
I think I might have found the perfect solution to your problem.
Yes, 0 and any non-zero number are False and True respectively. Though there is no boolean data type in C.
But this is not the problem, the actual problem is how you are dealing with the modification of variable a in the your code :
int a = 16;
while (a--){
printf("%d\n", a);
}
When the compiler comes to the while (condition) statement, first the value of a is read by the compiler for the condition, then the arithmetic operation takes place, in this case,
a = a - 1 / a -= 1. So in the end there will be a case when a = 1 and the condition satisfies and after the arithmetic operation a-- which leads to a = 0, the print statement prints a as 0.
The above scenario depends on whether you use --a or a--. These two statements are read by the compiler in the order they are written.
For --a first the operation is performed on a then its value is read and vice-versa for the other.
So for case --a when a = 1 first the operation is done i.e a = a - 1 / a -= 1 and then a is evaluated for the condition, which then comes out to be Falsy as a = 0. Try the code below :
int a = 16;
while (--a){
printf("%d\n", a); // prints numbers from 15 to 1 as intended
}
OR deal with the modification of a inside the while loop block.
int a = 16;
while(a){
a = a - 1; // or a -= 1
printf("%d\n", a); // also prints numbers from 15 to 1 as intended
}

Expressions in c return 1 for true

In c programming ,all non zero numbers can be used in conditional expressions to return true. In that aspect why do expressions which evaluate to true return 1 ,not any other non zero value?
#include<stdio.h>
int main()
{
printf("%d",6==6);
}
output: 1
This is defined in the C standard:
6.5.13 Logical AND operator
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
Similar for the other logical operators.
It makes a lot of sense to have a deterministic value for these cases, and the lowest positive non-zero value is a good candidate for that.
C11 draft
6.5.9 Equality operators
3
The == (equal to) and != (not equal to) operators are analogous to the
relational operators except for their lower precedence.108) Each of
the operators yields 1 if the specified relation is true and 0 if it
is false. The result has type int. For any pair of operands, exactly
one of the relations is true.
Because as you said, evaluating the both sides of that kind of expressions, the result could be true or false, that is a boolean value. By definition and convetion, in C standard, boolean values are represented with a 1 for true and 0 for false.

Why use !!(condition) instead of (condition)? [duplicate]

This question already has answers here:
What does !!(x) mean in C (esp. the Linux kernel)?
(3 answers)
Closed 9 years ago.
I've seen code where people have used conditional clauses with two '!'s
#define check_bit(var, pos) (!!((var) & (1 << (pos))))
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)
are some of the examples I could find.
Is there any advantage in using !!(condition) over (condition)?
Well if the variable you are applying !! is not already a bool(either zero or one) then it will normalize the value to either 0 or 1.
With respect to __builtin_expect this kernel newbies thread discusses the notation and one of the responses explains (emphasis mine):
The signature of __builtin_expect
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html) is:
long __builtin_expect (long exp, long c)
Note that the exp parameter should be an integral expression, thus no pointers
or floating point types there. The double negation handles the conversion from
these types to integral expressions automatically. This way, you can simply
write: likely(ptr) instead of likely(ptr != NULL).
For reference in C99 bool macro expands to _Bool, true expands to 1 and false expands to 0. The details are given in the draft standard section 7.16 Boolean type and values .
Logical negation is covered in 6.5.3.3 Unary arithmetic operators in paragraph 5:
The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
The unary ! logical negation operator, applied to any scalar, yields the int value 0 if its operand is non-zero, 1 if the operand is equal to zero. Quoting the standard:
The expression !E is equivalent to (0==E).
Applying ! twice to the same scalar value yields a result that's false if the value is false, true if the value is true -- but the result is normalized to 0 or 1, respectively.
In most cases, this isn't necessary, since any scalar value can be used directly as a condition. But in some cases you actually need a 0 or 1 value.
In C99 or later, casting the expression to _Bool (or to bool if you have #include <stdbool.h> behaves similarly and might be considered clearer. But (a) the result is of type _Bool rather than int, and (b) if you're using a pre-C99 compiler that doesn't support _Bool and you've defined your own bool type, it won't behave the same way as C99's _Bool.
The biggest I can see, is that it will force (or normalize) the value into 1 or 0 (that is a boolean value) regardless of how the x or var expression expands (e.g. char or double or int or etc.).
It casts to a boolean, which can sometimes be useful.

Resources