简体   繁体   中英

Consider a C variant, where comparison operators return all bits set for true values and 0 for false

I'm looking at a question and can't seem to see how it would deviate from normal C. In C, 1 represents true (of course any non-zero value is also considered true) and 0 represents false. In what scenarios would a C variant deviate from traditional C, if we instead returned all bits set when conditions evaluate to true. To me it seems the same, but I know there must be an aspect im not considering, or just not thinking of the question in the right way. Would really appreciate a hint in the right direction.

An advantage is that nominally branchless selections can be written more easily:

// Select c or d based on comparison of a and b.
static int Select(int a, int b, int c, int d)
{
    int mask = a < b;
    return c & mask | d & ~mask;
}

In standard C, this can be written as return a < b ? c : d; return a < b ? c : d; , but that nominally involves testing a < b and then executing a branch instruction. Branch instructions often have deleterious effects on processor performance, and we seek to avoid them in high-performance code. So have a bit mask instead that can be used to make the selection using on logical instructions, not branches, could be beneficial in some circumstances.

However, questions like this are hypothetical and dated. A compiler might optimize a < b ? c : d a < b ? c : d . Or, even if using a mask is better, there is a question of how the compiler is going to generate it to implement a < b —that might in itself involve performing a test and executing a branch instruction, thus negating the benefit. So questions like this generally do not have good answers in isolation. They serve only in a classroom context to prompt or portray student familiarity with the material.

The reason "non-zero" is considered true is probably tied to the underlying CPU architecture. Most assembly languages implement conditional control flow by comparison opcodes (on x86 the cmp instruction is used, or other instructions will implicitly set the zero flag) that set the corresponding 'zero flag'. Then conditional branching instructions will test the zero flag and jump to a new location only if it is set.

The zero flag is set only if the value is zero, so it avoids an additional comparison instruction to check if a value is exactly equal to one.

For example, on x86 machines this:

int fn(int x)
{
    if(x) return 1;
    else  return 0;
}

would become (something like) this:

fn:
    cmp    edi, 0
    jz    .L2

    mov    eax, 1
    ret
.L2:
    mov    eax, 0
    ret

Assuming your question is "why does C treat non-zero values as true?" (which I wasn't completely sure about), then the reason is because it's the most efficient way to use the instruction sets that we have on modern hardware (that being said, the example above is unnecessary and inefficient, but just to show the point).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM