V: if bug

Created on 10 May 2020  Â·  15Comments  Â·  Source: vlang/v

V version: V 0.1.27 1bf13f8
OS: Linux

What did you do?

fn main() {
    a := if 1 < 2 {
        b := 3
        b + 4
    } else {
        5
    }
    println(a)
}

What did you expect to see?
Either successful compilation or a meaningful error from the V compiler

What did you see instead?

==================
/home/elias/.cache/v/sandbox.tmp.c: In function ‘main’:
/home/elias/.cache/v/sandbox.tmp.c:9445:24: error: expected ‘)’ before ‘b’
 9445 | int a = (1 < 2 ?  ( int b = 3;
      |                   ~    ^~
      |                        )
/home/elias/.cache/v/sandbox.tmp.c:9446:13: error: expected expression before ‘:’ token
 9446 |  , b + 4 )  :  ( 5 ) );
      |             ^
/home/elias/.cache/v/sandbox.tmp.c: In function ‘vcalloc’:
/home/elias/.cache/v/sandbox.tmp.c:4493:1: warning: control reaches end of non-void function [-Wreturn-type]
 4493 | }
      | ^
...
==================
(Use `v -cg` to print the entire error message)

builder error: C error.
Bug

Most helpful comment

This should compile, this will be fixed.

All 15 comments

If/Match expressions are transpiled to C ternary operations, these cannot contain statements.

This should compile, this will be fixed.

I was looking at this exact issue today in relation to returning concat/multi-expressions from if/match expressions. This seemed like it would require a lot of rewriting to replace the ternary operation with if/else statements. Are you planning on working on this any time soon?

This can be fixed by using a tmp variable in most cases

Unless we have something like

if 1 < 2 {
        b := 3
        b + 4
    } else {
        5
    }
+
if 1 < 2 {
        b := 3
        b + 41
    } else {
        51
    }

which is crazy and can be not allowed by the compiler

So if an if expression has more than one statement, a tmp variable and a simple if are used instead of ?: in C.

Yes, so all cases where the expression is used in the right-hand-side will need to write the if-else statement before the left-hand-side.
Eg. return if true { 1 } else { 2 }
This is currently a nice single line in C. After the fix it should write the expression before the return:

int tmp;
if (true) {
  tmp = 1;
} else {
  tmp = 2;
}
return tmp;

I am suspecting there will be cases where this creates complications in cgen.

You didn't read my proposal thoroughly :)

if an if expression has more than one statement

In your example there's one statement, so nothing will change.

In fact, it even kind of works with multiple statements with C's weird , operator, just not for variable assignments.

The 1 and 2 were just placeholders :) imagine there being statements/variable declarations inside the blocks.

This already works:

fn main() {
       a := if 1 < 2 {
               println('hello')
           4
       } else {
           5
       }
       println(a)
   }

And I suspect it might even work with var declarations, it's jus generating bad C for some reason

int a = (1 < 2 ? ( int b = 3;

no it doesn't work with declarations, I tried :)

Doesn't work/compile:

void main() {
        int foo = (2 > 1) ? (int bar = 2, bar + 1) : 3;
}

Works:

void main() {
        int bar;
        int foo = (2 > 1) ? (bar = 2, bar + 1) : 3;
}
if 1 < 2 {
        b := 3
        b + 4
    } else {
        5
    }
+
if 1 < 2 {
        b := 3
        b + 41
    } else {
        51
    }

I don't think this example is crazy. You could for example generate C code like this:

int b1, b2;
((1 < 2) ? (b1 = 3, b + 4) : 5)
+ ((1 < 2) ? (b2 = 3, b + 41) : 51);

or even

bool v1 = 1 < 2;
int v2;
if (v1) {
    int v3 = 3;
    v2 = v3 + 4;
} else {
    v2 = 5;
}
bool v4 = 1 < 2;
int v5;
if (v4) {
    int v6 = 3;
    v5 = v6 + 41;
} else {
    v5 = 51;
}
int v7 = v2 + v5;

which should easily be possible by walking the AST. For translation to X64 machine code you need something similar to this anyway.

I agree with @eyelash - it'll be needed anyway for the ASM backend.

Closing as this issue has been fixed in #4860. Testing on V 0.1.27 034bf46 works too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shouji-kazuo picture shouji-kazuo  Â·  3Comments

XVilka picture XVilka  Â·  3Comments

cjmxp picture cjmxp  Â·  3Comments

lobotony picture lobotony  Â·  3Comments

PavelVozenilek picture PavelVozenilek  Â·  3Comments