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

我正在查看OpenSSL中使用的一些预处理器宏,我从crypto/stack/safestack.h看到了以下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的目的是什么,因为它总是如此?

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

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

一个简单的例子:

 int* p = NULL ; 1 ? p : ( float* )p ; //error 1 ? p : ( int* )p ; //ok 

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

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

条件运算符

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

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

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