When is (x || !x) false? - c

A friend of mine jokingly asked me this question. It was meant to be a "goes without saying" type remark, but then I actually thought about it for a while and started coming up with some clever "almost solutions".
First attempt:
If C ever supports quantum computing there may be an answer to this. A q-bit can be in many states at once, so it could be false AND true and this conditional will return (BOOL)0.5 aka "Yes/no/maybe-so" - but once you observe the variable the whole thing will collapse and become invalid again.
Second attempt:
If X could somehow be defined as a random binary generator and you cast it to a BOOL you could get false some of the time. I'm not sure if you can do this though in C unless you use CLANG. #define x (BOOL)!!(rand()%2)
The language we were discussing this in is C but I'm also curious if anyone can find any solutions in any language.

When x is volatile (volatile int x) and is modified by an external thread / device, the expression can be false.

It's a bit of a trick, but the following solution also works:
#define x 1 ? 0 : 1
(x || !x)
The reason is in the operator precedence. After preprocessing (x || !x) resolves to the following (parentheses added to show the precedence):
(1 ? 0 : (1 || !1) ? 0 : 1)

Macros are really cheating here, but you don't need anything to do with boolean types or special compilers. The following, as far as I know, is legal standard C.
#include <stdio.h>
int f(void) {
static int y = 0;
if (y == 0) {
y = 1;
return 0;
} else {
return 1;
}
}
#define x f()
int main(void) {
if (x || !x) {
puts("It was true");
} else {
puts("It was false");
}
return 0;
}
Or even more concisely:
int y = 0;
#define x y++
(For those worried about undefined behavior, note there is a sequence point between the left and right side of ||.)

An even simpler macro:
#define x 0&0
expanding (x || !x) gives (0 & 0 || !0 & 0) which is always false.
Similarly:
#define x 0*0
#define x 1*0 // for binary buffs
#define x 4&2 // for HHGG fans.
I could not find a 2 letter macro :(

Tried in JS:
var i = 0
i++ || !(i++)
Note: this solution works only when i = 0

Related

Can i do Multiple tasks by the conditional operator?

Can we write multiple commands like in if statement {between brackets} in conditional operators ?
(For knowledge, not for use)
if (x == 1) {
printf("Printf");
scanf("%d", &scanf);
callFun(calling a function);
}
else if (x == 2) {
printf("Printf2");
scanf("%d", &scanf2);
callFun2(calling a function);
}
int foo(int x)
{
int g,h;
(void)( x == 1 ? ( printf("Hello\n"), scanf("%d", &g), callfunc(g)) : x == 2 ? ( printf("Hello2\n"), scanf("%d", &k), callfunc(h + 5)) : 0);
}
Very easy to read as you see. Better use ifs
This looks clean in my opinion
#include <stdio.h>
void func(){
puts("working");
}
void func1(){
puts("working 2");
}
int main(){
int i = 21;
i == 2122 ? func() : func1();
return 0;
}
This also works
int main(){
int i = 21;
i == 2122 ? (
puts("working 1"),
puts("working 2")
) : (
puts("working 3"),
puts("working 4"));
return 0;
}
The ?: is less generic than if since it requires operands that are expressions. Furthermore it requires both operands to be of the same type. In some cases when they aren't, C implicitly tries to convert them by applying the implicit "usual arithmetic conversions" on the 2nd and 3rd operands. This can lead to unexpected results. For example this code prints gibberish:
printf("%d\n", 1 ? 1 : 1.0);
Even though the 3rd operand is never evaluated, the 2nd operands gets implicitly promoted to double and printing that with %d gives undefined behavior.
To avoid subtle stuff like this, the ?: should be avoided most of the time. It's main purpose in the C language is actually to enable conditions inside function-like macros that return a value. For example we obviously can't write a macro returning a value like this:
#define M(cond) if(cond) { foo(); } else { bar(); }
But it could be done like this:
#define M(cond) ( (cond) ? foo() : bar() )
Similarly, the , comma operator's main purpose is also to enable such macros. So yeah, you could rewrite the code you've written with the ?: in combination with the comma operator. But it's a very bad idea since such code turns unreadable. The only place where it might be justified is inside a function-like macro:
#define M(x) ( x==1 ? (printf("Hello\n"), scanf("%d", &something), callFun(something)) \
: x==2 ? (printf("Hello2\n"), scanf("%d", &something), callFun2(something)) \
: 0 )
This macro would return whatever callFun and callFun2 returns, assuming they return compatible types.
And in case it isn't obvious, function-like macros like these are very bad practice and actual functions are always preferred when possible. Writing macros such as this is should be a last resort, like for example when maintaining some crappy code base where you can't change certain things.
It would be a weird and thus undesireable thing to do, but it can be done.
The key is to use a comma operator instead of separate statements.
(
x == 1 ? (
printf("Printf"),
scanf("%d", &scanf),
callFun(calling a function)
)
: x == 2 ? (
printf("Printf2"),
scanf("%d", &scanf2),
callFun2(calling a function)
)
: (void)0
);

How is 0 used in conditional operator in C?

Conditional operator in C is used like this:
condition ? value_if_true : value_if_false
What does 0 mean when it's used in the value_if_false?
I've seen some people using it like this, for example.
a == b ? i++ : 0
It seems like it does nothing. Does this work like return 0 in other functions?
In C language, ternary is shorter version of if statement and it requires both statements, if_true and if_false. It would be like this (in fact it can have multiple statements for one case, separated with comma):
Short:
condition ? if_true : if_false;
Long:
if (condition) {
if_true;
} else {
if_false;
}
You can also assign the value if you put something infront of condition.
Short:
result = condition ? if_true : if_false;
Long:
if (condition) {
result = if_true;
} else {
result = if_false;
}
Now here is the trick. In C language, writing 0; is a valid statement, so your ternary becomes in longer version same as code below:
if (a == b) {
i++;
} else {
0; /* This is valid C statement */
}
Or if you have assignment too, it would be:
if (a == b) {
result = i++;
} else {
result = 0;
}
You can also do this:
int a;
/* Code here ... */
condition ? a = 5: 0;
That is effectively the same as:
if (condition) {
a = 5;
} else {
/* DO not touch a */
}
The ?: operator is a ternary operator, but it is not called "ternary" as some answers and/or comments here suggest. It just is the arity of the operator, just as + is a binary operator or as & is unary. If it has a name at all, it is called "Conditional Expression"-operator
It is not quite equivalent to if/else, because it is a conditional value (with the consequence, that both expressions must have the same type) in the first place, not a conditional execution. Of course, both types can be cast to make them equal.
In the case of what the OP does, a better option (if if shall not be used) is in my opinion:
a == b && i++;
which resembles a bit more logical what happens. But of course it is a matter of style.
The reason why someone might want to write a == b ? i++ : 0; is that s/he probably wants to have an (Caution! You are now entering an opinion-based area) easier and faster alternative to if (a == b) i++; - although this is of course opinion-based and I personally not share the same opinion.
One thing I can think of as a "blocker" at the if statement is the requirement to write the parentheses () which can be omitted by using the conditional operator instead.
"But why the 0?"
The C syntax requires a third operand for the conditional operator. Else if you would want to compile for example:
a == b ? i++;
you will get an error from the compiler:
"error: expected ':' before ';' token"
Or respectively, doing so:
a == b ? i++ : ;
would raise:
"error: expected expression before ';' token"
So they use 0 as kind of "syntax satisfier" to be able to use the conditional operator as replacement for the if statement. You could use any other numeral value here as well, but 0 is the most readable value, which signifies that it has no use otherwise.
To showcase the use at an example:
#include <stdio.h>
int main (void)
{
int a, b, c = 4;
a = 2;
b = 2;
a == b ? c++ : 0;
printf("%d",c);
return 0;
}
The output for c will be 5, because a == b.
Note that a == b ? i++ : 0 is different when used f.e. inside of an assignment like f.e.:
int c = a == b ? i++ : 0;
Here c is either getting assigned by i or 0, dependent upon a == b is true or not. If a == b is true, c is assigned by i. If a == b is wrong, c is assigned by 0.
Side Notes:
To view it from a technical point, ?= is called the "conditional operator". The conditional operator is one of the group of ternary operators.
If you want to learn more about the conditional operator ?=, look at ISO:IEC 9899:2018 (C18), ยง6.5.15 - "Conditional operator" for more information.
There's nothing special about 0 one could write
a == b ? i++ : 1
And it would behave the same way.
Only difference is when you assign the expression to say another variable:
int c = a == b ? i++ : 1;
// a == b -> c will be i++
// a != b -> c will be 1
However it's much cleaner to write
if (a == b) i++;
It helps to think of the ternary operator as a shorthand way or writing an if-else statement.
If(a == b){
i++;
}else{
//if assigned, return 0. Else do nothing.
}

C: flip integer value as a boolean

I'm looking a way to flip an integer value (8bits) using it as a boolean (0 -> False, 1 -> True).
On many languages you can do val = !val to change the value. The only thing I have done is val = (val == 1) ? 0 : 1. I don't know if in C can work with a bite value.
It is for an old hardware with a 8bit processor, so the idea of use boolean is not possible, and I can't install external libraries.
In C a value of 0 is considered "false", and any other (nonzero) value is considered "true". So one, very explicit way to convert an arbitrary int value to an explicitly true-or-false Boolean value is to use the (C99 and later) bool type:
#include <stdbool.h>
int i;
bool b;
b = (i != 0) ? true : false;
But since the != operator essentially "returns" a Boolean value, you can also do
b = (i != 0);
And since the zero/nonzero definition is built in to the language, you can also just do
b = i;
But you don't have to use type bool. If you have an arbitrary-value int and you want to force it to 0/1 "in place", you have the same sorts of options:
i = (i != 0) ? 1 : 0;
Or
i = (i != 0);
Or there's another common trick:
i = !!i;
This last is concise, popular, and somewhat obscure. It changes zero/nonzero to 1/0 and then back to 0/1.
I've shown these examples using type int, but they would all work just as well with short int or char (i.e. byte).
One more thing. In your question you wrote val = (val == 1) ? 0 : 1, but that's basically meaningless. In C, at least, everything (everything!) follows from whether a value is zero or nonzero. Explicit comparisons with 1 are almost always a bad idea, if not a downright error.
I posted one answer, but I may have misread the question. If you have an integer variable -- it might be int, short int, or char -- and you want to have it cycle back and forth 0, 1, 0, 1 (which you can interpret as false, true, false, true), there are two about equally good ways to do it. You could do:
i = !a;
This first way emphasize the "Boolean" nature of the variable.
Or, you could do:
i = 1 - i;
This second way is purely numeric.
But either way will work perfectly well. In either case, i is guaranteed to alternate 0, 1, 0, 1, ...
You could also use
i = i ? 0 : 1;
or
i = (i == 0) ? 1 : 0;
Both of these will work, too, but they're basically equivalent to i = !i.
In your question you suggested
i = (i == 1) ? 0 : 1;
This would mostly work, but it looks weird to my eye. Also it would do the wrong thing if i ever ended up containing 2 (or any value other than 0 or 1).
Adding to Summit's answer, you can also do this:
#define TRUE ~0U
#define FALSE 0U
#ifndef BOOL
#define BOOL unsigned int;
#endif
int main() {
BOOL var = TRUE;
var = ~var; //Negate var and set it to false.
var = ~var; //Negate var again and set it to true.
return EXIT_SUCCESS;
}
If you are using at least C99, then you can change
#ifndef BOOL
#define BOOL unsigned int;
#endif
to:
#include <stdint.h>
#ifndef BOOL
#define BOOL uint_fast8_t;
#endif

Strange things happen with bool? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
Why with variable a do I need to use the symbol =, but with variable b GCC tells me to use ==? Should they all being used with =, am I wrong or what? If I use a normal if, this thing doesn't happen.
P.S: I know about the <stdbool.h>.
Thanks everyone.
#define FALSE 0
#define TRUE 1
typedef int BOOL;
int main()
{
BOOL a;
BOOL b;
int num = 21; // random number
(num == 21) ? a = TRUE : b = TRUE;
return 0;
}
It's tricky at first. But there is a simple reason why GCC complains.
(num == 21) ? a = TRUE : b = TRUE;
Here, the colon operator takes precedence over equal to operator. So effectivey, this statement is evaluated as
((num == 21) ? a = TRUE : b) = TRUE;
which in turn is the same as
TRUE = TRUE;
So the compiler rightly complains that lvalue required as left operand of assignment. However, if you use parenthesis to correct the affinity, it won't complain.
(num == 21) ? (a = TRUE) : (b = TRUE); //No compiler error
If you were trying to do this:
(num == 21) ? a = TRUE : b = TRUE;
The syntax is invalid due to operator precedence. The ternary operator ?: has higher precedence than the assignment operator =. So the expression above is the same as:
((num == 21) ? a = TRUE : b) = TRUE;
This is invalid syntax because you can't have an expression like this on the left side of an assignment.
You need to add parenthesis to get the behavior you want.
(num == 21) ? a = TRUE : (b = TRUE);
Here is a better code using stdbool.h library. = & == are direfferent ! The first one is used for asignation and the second one for a comparing
#include <stdio.h>
#include <stdbool.h>
int main(void){
bool a = false;
bool b = false;
int num = 21; // random nr lol
bool result = (num == 21) ? true : false;
a = result;
b = !result;
return 0;
}
It is equivalent to
((num == 21) ? a = TRUE : b) = TRUE;
Thus, you are assigning to the result of expression, but not to the variable. Therefore compiler demands == operator.
Use
(num == 21) ? a = TRUE : (b = TRUE);
This type of syntax is called a ternary operator. They are generally used to perform simple expressions, or assign things to ONE variable based on a condition, rather than handle assignment logic with two variables.
This is why you can't have both a = TRUE and b = TRUE in the ternary operator. You should only have values or things that return values in there.
e.g.
BOOL result = (num == 21 ? TRUE : FALSE);
BOOL a = result;
BOOL b = !result;
Read more on ternary operators on Mozilla's documentation
Also, slightly unrelated to your actual question, but still an issue you should fix; Lee Daniel Crocker made a good point. FALSE shouldn't really be defined as 1, as it is usually defined as 0 in most programming contexts. TRUE is defined as any number other than 0, i.e. !FALSE. Hence, try doing this to define your TRUE and FALSE:
#define FALSE 0
#define TRUE !FALSE

Why am I getting the answer "odd" instead of "even"

Why am I getting the answer "odd" instead of "even"?
#include<stdio.h>
#define ODD(x) x%2?0:1
int main()
{
int a=5;
if(ODD(a+1))
printf("even");
else
printf("odd");
return 0;
}
ODD(a+1) expands to a+1%2?0:1. With a as 5, that is same as (5+(1%2))?0:1 or 0.
% beats + which beats ?:
if(0)
printf("even");
else
printf("odd"); // print `odd`
Perhaps you wanted some () to insure evaluation order.
// #define ODD(x) x%2?0:1
#define ODD(x) ((x)%2?0:1)
Yet that seems backwards. How about
#define ISODD(x) ((x)%2 != 0)
See How do I check if an integer is even or odd?
1 is treated as true and 0 as false.
if (1) is executed always, and when you get 0 as result, the branch shifts to else
so code should be :
if ODD is true (returning 1 from terneray expression), print "odd"
#define ODD(x) x % 2 ? 0 : 1
Given an even number x, x % 2 will give you zero, which is false.
Hence the result of the entire ternary expression will be the second option 1, which is true.
You would be better off with something like:
#define ODD(x) (((x) % 2) != 0)
It's both more readable in intent, and less prone to errors such as getting the true/false values mixed up, or being burnt by simple text substitution having unexpected effects.
I do not like this kind if macros for many reasons (one of it that they can be a source of silly errors - like in your case). It should be domain of functions.
int ODD(int x)
{
return x & 1;
}
if you are worried about function call overhead just make it inline (but on any level op optimisation the compiler will inline it anyway as the call is probably longer than the function itself.

Resources