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

jww*_*jww 27 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)))
Run Code Online (Sandbox Code Playgroud)

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

使用1上述内容的目的是什么,因为它始终如一?

250*_*501 25

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

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

一个简单的例子:

int* p = NULL ;

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

1 ? p : ( int* )p ;      //ok
Run Code Online (Sandbox Code Playgroud)


maf*_*fso 13

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

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

条件运算符

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

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

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