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
是函数指示符).