Topic: Encountering else without having executed an if, was: Re:


Author: greghe@pacbell.net (Greg Herlihy)
Date: Mon, 16 Apr 2007 08:00:49 GMT
Raw View
On Apr 15, 5:51=A0pm, "James Kanze" <james.ka...@gmail.com> wrote:
>
> =A0If I write something like:
>=20
> =A0 =A0 bool c =3D false ;
> =A0 =A0 goto toto ;
> =A0 =A0 if ( c ) {
> toto:
> =A0 =A0 =A0 =A0 stmt1 ;
> =A0 =A0 } else {
> =A0 =A0 =A0 =A0 stmt2 ;
> =A0 =A0 }
>=20
> what should happen? =A0The condition is false; should the else
> part be executed.

No. The program above would have to execute the if-statement with a
condition that yields false in order to transfer control to the
if-statement's associated "else" clause. But a goto statement in the abov=
e
program bypasses the if-statement - thereby preventing the if-statement f=
rom
executing at all. So the if-statement has no opportunity to evaluate its
condition - or to to transfer control to its associated else sub-statemen=
t -
simply by virtue of the fact that the if-statement itself is never execut=
ed.

> > Therefore the
> > only possible interpretation is that the condition result is effectiv=
ely
> > preserved.
>=20
> How do you preserve it in the above. =A0It hasn't ever been
> evaluated.

Exactly. Since the if-statement is not executed, the if-statement selects
neither of its sub-statements for execution. In fact, it follows that the
only way for a C++ program to execute either sub-statment associate with =
an
unexecuted if-statement, is for the program to execute a goto statement t=
hat
transfers control into one of the sub-statement blocks directly.
=20
> The original issue was in code something like (from memory):
>=20
> =A0 =A0 void
> =A0 =A0 foo( bool b )
> =A0 =A0 {
> =A0 =A0 =A0 =A0 switch (1) {
> =A0 =A0 =A0 =A0 =A0 =A0 if ( b ) {
> =A0 =A0 =A0 =A0 case 1:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 std::cout << "1 " ;
> =A0 =A0 =A0 =A0 =A0 =A0 } else {
> =A0 =A0 =A0 =A0 case 2:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 std::cout << "2 " ;
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 }
> =A0 =A0 }
>=20
> =A0 =A0 int
> =A0 =A0 main()
> =A0 =A0 {
> =A0 =A0 =A0 =A0 foo( false ) ;
> =A0 =A0 =A0 =A0 foo( true ) ;
> =A0 =A0 =A0 =A0 std::cout << '\n' ;
> =A0 =A0 =A0 =A0 return 0 ;
> =A0 =A0 }
>=20
> Different compilers (and different versions of the same
> compiler) were doing different things. =A0One compiler, in
> particular, output "1 2 1 2" (whereas most others output "1 1").

"1 1" is the expected output. It is not possible for the program to execu=
te
the else clause (that would output "2") because a) the case 2 branch of t=
he
switch statement is never equal to the value that the switch-statement's
condition yields, and b) no label is present within the else clause that
would permit a goto statement to transfer control into the else block
directly.

> Given the language in the standard, I not sure I can say that
> this compiler wrong.

I think that the current language in the Standard is enough to define the
correct behavior. And to avoid making a change to the (normative) text th=
at
may be interpreted as a change in the Standard that could affect the
behavior of existing C++ programs, I would recommend adding an example
instead. In particular, I would suggest an example that illustrates a got=
o
statement that transfers control into the first substatement of an
if-statement. The purpose of this example would be to show that the
else-clause is not executed under such circumstances:

   [Example:=20
        int x(1);

        goto label1:
        if (x =3D=3D 0) {
        label1:
            x =3D 2;
        }=20
        else {=20
            x =3D 3;=20
        }=20
        ... // x has the value 2
    --end example]

Greg=20

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]