2011-02-27 23 views
0

我在C中实现了一个计算机模拟器,不接受使用条件的挑战(例如,没有if/else,switch/case,while/for等)。我正在模拟的硬件中有很多复用器,所以如果我可以使用条件三元逻辑运算器将会很好。所以,我的问题是:C编译器是否使用三元逻辑运算符创建MUX逻辑,还是创建分支?三元逻辑和多路复用器逻辑之间的连接?

实施例:

int a, b, q, r; 
/* Ternary logic */ 
r = q ? a : b; 
/* MUX equivalent logic */ 
r = (q & a) | ((~q) & b) 
/* Branch equivalent logic */ 
if (q) r = a; else r = b; 

回答

4

三元运算符相当于一个分支:即,不是返回的值不评估。

我不知道你有多少约束,所以请注意,布尔运算符&&||不要评估它们的第二个参数,结果可以从第一个确定。 (注意,你所在的行“MUX”与其他两个表达式没什么区别:它根据q中相应位的值选择来自a或b的位,它不选择a或b取决于q是否为空;编辑:更糟糕的是:您正在使用!q而不是〜q ...)。

+0

1.我知道三元运算符相当于一个分支,如上所述。我问的是,“编译器在汇编层面上生成了一个分支吗?” 2.我没有发现&&和||的任何用处布尔运算符到目前为止。我会记住你的见解。我对你使用“空白”一词感到困惑。但是你是对的,在大多数情况下,我应该切换到〜(这是一个简单的1位值的例子,但我会编辑它)。 – Robz 2011-02-27 14:02:30

+0

@Robz:1.一般来说,是的。 – 2011-02-27 14:07:04

+0

1.是的(它不能评估其他分支)。 3.零 – AProgrammer 2011-02-27 14:40:04

1

C编译器使用三元语句创建分支。

使用飞思卡尔的CodeWarrior IDE,我编译下面的C程序:

int a, b, q, r;  
void main(void) {  
    a = 0;  
    b = 1;  
    q = 0;  
    r = q ? a : b;  
.. 
..  
} 

对应于三元语句的组件如下:

... 
LDX 0x1104 ; load val[q] into register x  
BNE *+4 ; branch to abs addr 0xC016 if val[q]==a  
BRA *+5 ; branch to abs addr 0xC019 if val[q]!=a 
... 
1

通常,分支逻辑被创建,但如果两个值都被评估,那么很有可能在没有任何分支的情况下进行三元运算。这样考虑:

#include <stdio.h> 

static inline int isel(int cond, int a, int b) 
{ 
    int mask = cond | (-cond); 
    mask >>= 31; 
    return (b & mask) | (a & ~mask); 
} 

int main(void) 
{ 
    printf("1 ? 3 : 4 => %d\n", isel(1, 3, 4)); 
    printf("0 ? 3 : 4 => %d\n", isel(0, 3, 4)); 
    printf("-1 ? 3 : 4 => %d\n", isel(-1, 3, 4)); 
    return 0; 
} 

此代码假定符号数向右移位将符号扩展,而的sizeof(int)的== 4. 一些处理器可以做ISEL()作为组件指令。然而,这两个价值将被评估,三元?:不会。

根据情况的不同,编译器通常会尽量做最快的事情,要么是分支来避免冗余计算,要么是在三元表达式中的值很简单的情况下做这种逻辑。

+0

酷!我使用了一个带有位域的结构体来扩展位信号,但是这也起作用,谢谢!我原本以为编译器会不惜一切代价避免分支,但正如你所说,检查“冗余计算”也是有意义的。 – Robz 2011-02-28 03:01:10