Opened 8 months ago

Last modified 7 weeks ago

#290 new defect

Two-Argument Conditional Revaluates Condition

Reported by: ajbeach Owned by:
Priority: major Component: cfa-cc
Version: 1.0 Keywords:
Cc:

Description ΒΆ

The two-argument conditional currently is implemented as a short hand and evaluates its condition twice instead of once. For example the following piece of code prints "yes" twice instead of once:

bool yes() {
    printf("yes\n");
    return true;
}

int main(int argc, char * argv[]) {
    bool result = yes() ?: false;
    printf("result: %s\n", result ? "true" : "false");
}

This is because, under the hood we copy the entire expression instead of using the result of one expression twice. To write it out in code:

condExpr ?: elseExpr
// Is treated as:
condExpr ? condExpr : elseExpr
// Should be treated as:
({ TYPE NAME = condExpr; NAME ? NAME : elseExpr; })

(Where TYPE and NAME are found internally, if they explicitly exist at all.) This will probably require some resolver trickery as the expression must be resolved so it can be used as both the condition-expression and then-expression.

It is also theoretically possible to construct a case where one of the condition and then-expression are resolved differently than the expression that should be used in both locations. Or even both. I haven't constructed such a case and expect it is extremely rare in practice.

Change History (1)

comment:1 Changed 7 weeks ago by ajbeach

Here is another interesting example of the problem, that also shows how the error also interacts with the resolver:

short first() {
    printf("short first 0\n");
    return 0;
}

short second() {
    printf("short second 2\n");
    return 2;
}

int first() {
    printf("int first 1\n");
    return 1;
}

int main() {
    first() ?: second();
}

This has the following output:

int first 1
short first 0

This means that not only did first() get called twice but it was not resolved the same in its two uses.

Note: See TracTickets for help on using tickets.