在开放源码这码我跑过这一行代码:

machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */

这只是一个混乱的方式说:

if (machine->max_cpus) {
   ; //do nothing
} else {
 machine->max_cpus = 1;
}

如果是这样,那岂不是更加清晰:

if (machine->max_cpus == 0) machine->max_cpus = 1;

有趣的是,这种编纂工作和现有海湾合作委员会,但不会汇编上 http://www.comeaucomputing.com/tryitout/ .

有帮助吗?

解决方案

这是在GNU允许如一个晦涩延伸到C

  

5.7条件句省略操作数

     

在条件的中间操作数   表达可被省略。然后,如果   第一操作数非零,它的值是   条件的值   表达

     

因此,表达

 x ? : y
     

具有x的值,如果这是非零;   否则,y的值。

     

此例子完全等价   到

 x ? x : y
     

在这个简单的例子中,能够   省略中间操作数不   特别有用。当它成为   有用是当第一操作数确实,   或者可以(如果它是一个宏参数),   包含的副作用。然后重复   在中间操作数将   执行两次副作用。   省略中间操作数使用   值已经计算无   重新计算它的不期望的效果。

正如你可能已经猜到,避免这种建议的可读性和可移植性的原因。我惊讶诚实看到这样的语法不兼容的扩展C.

其他提示

这是一个 GCC扩展程序,意思是“如果条件为真,则使用它,否则使用该其他值”,所以

machine->max_cpus = machine->max_cpus ?: 1;

为简写

machine->max_cpus = machine->max_cpus ? machine->max_cpus : 1;

虽然如果条件有副作用,它将只运行一次

使用GCC的-pedantic标志,它说

  

foo.c的:5:警告:ISO C不允许   省略的中间项?   表达

这是一个 GCC扩展和它变得更有趣的和有用的,当条件有副作用。

在这种情况下,是的,我一会同意它的晦涩比什么都重要。

在K&R BNF显示之间需要表达式 “?”和 “:”。我并不认为海合会应编译,没有一个诊断。

还有另外一个有用的情况下,对于这种--消除中间变量时调用一个功能或方法可能会返回nil,我们希望避免调用的两倍。例如(目标-C),假设我们要解开一个文件阵列,如果它存在,否则返回的一个空阵列。

- (NSArray*)hydrateBacklogFromFile:(NSString *path)
{
    NSArray *backlog = @[];
    NSData *backlogData = [NSData dataWithContentsOfFile:path];
    if (backlogData)
    {
        backlog = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData] ?: backlog;
    }
    return backlog;
}

该方案是较为简洁。

- (NSArray*)hydrateBacklogFromFile:(NSString *path)
{
    NSArray *backlog = @[];
    NSData *backlogData = [NSData dataWithContentsOfFile:path];
    if (backlogData)
    {
        NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData];
        if (tempArray != nil)
        {
            backlog = tempArray;
        }
    }
    return backlog;
}

或丑陋的多返回等。

- (NSArray*)hydrateBacklogFromFile:(NSString *path)
{
    NSData *backlogData = [NSData dataWithContentsOfFile:path];
    if (backlogData)
    {
        NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData];
        if (tempArray != nil)
        {
            return tempArray;
        }
    }
    return @[];
}

所以它是非常有用的语法糖,我觉相当的可读性。缺点是

  • 隐性转换的一个指bool。这是一个长期C 《公约》,但是大多数现代语言禁止它,复杂 任何移植的努力。

  • 正如其他人所说它也是一个非标准的扩展,所以它应该 可以避免的,如果可移植性是一个考虑因素。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top