Is if condition valid?

I

Immortal Nephi

I was curious to examine C source code. C source code has a lot of
macros. How is C++ Compiler able to convert the statement into if
condition? Do it recognize (void) if it is to be valid if condition?

void ret()
{
}

int main()
{
bool test = false;

(void) ( test || ( ret(),0 ) );

if( !test )
ret();

return 0;
}
 
I

Immortal Nephi

 application_pgp-signature_part
< 1KViewDownload



What does this have to do with macros in C source code?











The book you're reading to learn C++ should explain to you that the ||
operator is a "short-circuit" operator. Re-read what "short-circuit
evaluation" means, and you'll see why the above expression, and the above
if() statement, are functionally identical.- Hide quoted text -

Yes, I am learning C++. I do self-study at home. I develop my C++
source code for personal use. I often read Deitel How to program C++
book like I have said in the past.
I was unable to find short-circuit operator statement, but page 219
in Deitel book does explain short-circuit as if( … || … ), but it does
not say (void) ( … || ( func(), 0 ) ). I always know truth table.
 
K

Kai-Uwe Bux

Immortal said:
I was curious to examine C source code. C source code has a lot of
macros. How is C++ Compiler able to convert the statement into if
condition? Do it recognize (void) if it is to be valid if condition?

void ret()
{
}

int main()
{
bool test = false;

(void) ( test || ( ret(),0 ) );

Look as the comma operator in ret(),0. This subexpression is an int, not a
void.
if( !test )
ret();

return 0;
}


Best

Kai-Uwe Bux
 
Ö

Öö Tiib

        Yes, I am learning C++.  I do self-study at home.  I develop my C++
source code for personal use.  I often read Deitel How to program C++
book like I have said in the past.
        I was unable to find short-circuit operator statement, but page 219
in Deitel book does explain short-circuit as if( … || … ), but it does
not say (void) ( … || ( func(), 0 ) ).  I always know truth table.

(void) is there probably to remove return value (false, since false ||
0 is false.
 
J

Jonathan Lee

        I was unable to find short-circuit operator statement, but page 219
in Deitel book does explain short-circuit as if( … || … ), but it does
not say (void) ( … || ( func(), 0 ) ).  I always know truth table.

Short circuiting basically means that logical operators are evaluated
left to right, and only as far as necessary. Consider "A && B". The
'B' part won't be evaluated if A is false, because there's really no
need. 'A' being false guarantees that "A && B" is false, regardless
of the value of 'B'.

Similarly for "A || B", except evaluation of "or" quits at the first
true value encountered. So 'B' is only evaluated if 'A' is false.
That's more or less what you've got in your code. If 'test' is false,
then "(ret(), 0)" is evaluated. But it isn't evaluated when 'test'
is true. Therefore, it is equivalent to the "if (!test) ret();"

I think most people regard code like "(test || (ret(),0))" as an
obfuscation, however. A bit of an abuse of the language, in my
mind.

--Jonathan
 
I

Immortal Nephi

 application_pgp-signature_part
< 1KViewDownload








"Short-circuit" is not a statement, but a description. If your book, in its
description of || and &&, does not mention that they're so-called
"short-circuit" operators, and does not explain what "short-circuit" means,
then you should look around for a better book.


When you have a statement:

if ( expression )
{
    statement;

}

You know that if the "expression" evaluates to any non-0, or true, the
"statement" part is processed. If it evaluates to 0, or false, "statement"
is not processed.

This is very similar to:

( expression1 || expression2 )

If "expression1", which can be any expression, and evaluates to any non-0
value, then "expression2" does not get evaluated at all, because this is a
logical-or operation, and since you understand truth tables, you already
understand that the entire expression will be true. Therefore, "expression2"
is not evaluated, it is "short-circuited". If "(expression1 || expression2)"
is a part of a larger expression, its value will be true when "expression1"
evaluates to true, the rest of the expression then evaluated,
short-circuiting the "expression2" part, which does not get evaluated.

If you think about it, this is exactly the same as

if (expression1)
{
    expression2;

}

There are only two minor differences between the || and the if() statement,
in C or C++. With the if() statement you can use any statement, or a
compound statement, for its conditional part (an expression is always a
valid statement). The right-hand side of the || operator is limited to an
expression (ignoring, for the moment, compiler-specific extensions, such as
a gcc-specific syntax for inserting statements in place of expressions).
Also, the body if the if() statement gets evaluated if the if() expression
is true, but the right-hand side of

Therefore, when you have:

(something || functioncall())

If "something" evaluates to true, the right-hand side of the || operator
does not get evaluated and the function call does not take place. This is
exactly identical to:

if (!(something))
{
    functioncall();

}

The (void) part in the original code is just an explicit declaration that
the result of the || operator is to be discarded. It carries no meaningful
effect except as an explicit declaration that the expression's result is
discarded, which would occur anyway.

The same holds true for the && operator. Your homework assignment is to
understand why if

(expression1 || expression2)

is equivalent to

if (!(expression1))
{
    expression2;

}

then why

(expression1 && expression2)

is equivalent to

if (expression1)
{
    expression2;

You are correct to state that short circuiting is used if logical
operators are evaluated left to right.
I am not sure I understand what comma between func() and 0 mean.
" (func(), 0 ) "

(void) ( condition || ( func(), 0 ) )

If condition is false, then ( func(), 0 ) is evaluated. Do you
suggest to avoid using this statement above because it is so
confusing?
 
I

Ian Collins

Please trim your posts!
You are correct to state that short circuiting is used if logical
operators are evaluated left to right.
I am not sure I understand what comma between func() and 0 mean.
" (func(), 0 )"

It's the comma operator, seldom used. In this case, it's used to the
the expression a type. Try the code without it and see what your
compiler says.
(void) ( condition || ( func(), 0 ) )

If condition is false, then ( func(), 0 ) is evaluated. Do you
suggest to avoid using this statement above because it is so
confusing?

Yes. It's horrible!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top