Thread overview
else not attaching properly to if
Oct 29, 2007
nobody
Oct 29, 2007
Don Clugston
Oct 29, 2007
nobody
Oct 29, 2007
Matti Niemenmaa
October 29, 2007
I do not think it should ever be the case that this block:

  if(false)
    if(true)
    {
      assert(false);
    }
  else
  {
    assert(true);
  }

should ever be functionally different from this block:


  if(false)
  {
    if(true)
    {
      assert(false);
    }
  }
  else
  {
    assert(true);
  }

The compiler agrees with me in this simple case. However, I have found a spot in my code where the second block results in correct behaviour and the first block does not. This is surely a compiler (v1.015) bug? Here is the big picture:

  struct S
  {
    void f()
    {
      while()
      {
        foreach()
        {
          if(...)
          {
            if(...)
            {

            }

            else
              if(...)
              {

              }
          }

          else
          {
            if(...)
            { // need brackets or next else is not attached
              if(...)
              {

              }
            }
            else
            {
              if(...)
              {

              }

              else if(...)
              {

              }

              else if(...)
              {

              }

              else if(...)
              {

              }
            }
          }
        }
      }
    }
  }
October 29, 2007
nobody wrote:
> I do not think it should ever be the case that this block:
> 
>   if(false)
>     if(true)
>     {
>       assert(false);
>     }
>   else
>   {
>     assert(true);
>   }
> 
> should ever be functionally different from this block:
> 
> 
>   if(false)
>   {
>     if(true)
>     {
>       assert(false);
>     }
>   }
>   else
>   {
>     assert(true);
>   }

The else always wants to join to the most recent if.
The first snippet is equivalent to:

if (false) {
  if (true) {
    assert(false);
  } else {
    assert(true);
  }
}

So I can't see a bug in the bigger example.
October 29, 2007
nobody wrote:
> I do not think it should ever be the case that this block:
> 
>   if(false)
>     if(true)
>     {
>       assert(false);
>     }
>   else
>   {
>     assert(true);
>   }
> 
> should ever be functionally different from this block:
> 
> 
>   if(false)
>   {
>     if(true)
>     {
>       assert(false);
>     }
>   }
>   else
>   {
>     assert(true);
>   }
> 
> The compiler agrees with me in this simple case.

No, you've got it wrong. It's:

if (false) {
	if (true) {
		assert (false);
	} else {
		assert (true);
	}
}

Which compiles down to nothing since if (false) is always false.

The compiler appears to agree because both blocks actually do nothing. Compile and run this:

import std.stdio;

void main() {
	writefln("%d", f      (false,true));
	writefln("%d", f_wrong(false,true));
	writefln("%d", f_right(false,true));
}

int f(bool a, bool b) {
	if (a)
		if (b) {
			return 0;
		} else {
			return 1;
		}
	return 2;
}
int f_wrong(bool a, bool b) {
	if (a) {
		if (b) {
			return 0;
		}
	} else {
		return 1;
	}
	return 2;
}
int f_right(bool a, bool b) {
	if (a) {
		if (b) {
			return 0;
		} else {
			return 1;
		}
	}
	return 2;
}

-- 
E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
October 29, 2007
Don Clugston wrote:
> nobody wrote:
>> I do not think it should ever be the case that this block:
>>
>>   if(false)
>>     if(true)
>>     {
>>       assert(false);
>>     }
>>   else
>>   {
>>     assert(true);
>>   }
>>
>> should ever be functionally different from this block:
>>
>>
>>   if(false)
>>   {
>>     if(true)
>>     {
>>       assert(false);
>>     }
>>   }
>>   else
>>   {
>>     assert(true);
>>   }
> 
> The else always wants to join to the most recent if.
> The first snippet is equivalent to:
> 
> if (false) {
>   if (true) {
>     assert(false);
>   } else {
>     assert(true);
>   }
> }
> 
> So I can't see a bug in the bigger example.

You are right. I was wrong in thinking that the elimination in the case of single statements applied here, which it does not.