具有常量(true)值的条件运算符?

时间:2014-12-21 02:52:22

标签: c conditional-operator

我正在查看OpenSSL中使用的一些预处理器宏,我从crypto/stack/safestack.h发现了以下内容:

#define CHECKED_STACK_OF(type, p) \
    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))

#define CHECKED_SK_FREE_FUNC(type, p) \
    ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))

#define CHECKED_SK_FREE_FUNC2(type, p) \
    ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))

我猜测它的编写方式可以解决编译器错误(可能是供应商十多年来一直没有支持的古老的东西)。

使用上述1的目的是什么,因为它总是如此?

2 个答案:

答案 0 :(得分:25)

它的代码会仔细检查是否传递了正确的类型。指针p被传递,并且该指针的类型也必须在宏中手动输入。

三元表达式将始终返回第二个操作数,但如果它们的类型匹配,则将检查第二个和第三个操作数,如果它们没有,则应该得到编译器错误。

一个简单的例子:

int* p = NULL ;

1 ? p : ( float* )p ;    //error

1 ? p : ( int* )p ;      //ok

答案 1 :(得分:13)

它是关于强制转换之前的函数类型的静态断言,提供了类型安全的强制转换。

从C11(n1570)6.5.15(来自约束部分)

  

条件运算符

     

(3)以下其中一项适用于第二和第三个操作数:

     
      
  • [省略非指针内容]
  •   
  • 两个操作数都指向兼容类型的限定或非限定版本的指针;
  •   
  • 一个操作数是指针,另一个是空指针常量;或
  •   
  • 一个操作数是指向对象类型的指针,另一个是指向void的限定或非限定版本的指针。
  •   

第三个操作数是一个指向函数的指针(因此最后一个子弹永远不会应用),所以只有当p是空指针常量或者与{{{{1}兼容的类型时,才会编译(没有警告) 1}}用于最后一个宏(在转换为函数指针之后,如果void (*)(type)是函数指示符)。