检测宏中的整数常量表达式 [英] Detecting Integer Constant Expressions in Macros

查看:23
本文介绍了检测宏中的整数常量表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Linux 内核邮件列表中有一个关于宏的讨论,该宏测试其参数是否为整数常量表达式以及是否为整数常量表达式本身.

There was a discussion in the Linux kernel mailing list regarding a macro that tests whether its argument is an integer constant expression and is an integer constant expression itself.

一种不使用内置函数的特别聪明的方法,由 Martin Uecker 提出(从

One particularly clever approach that does not use builtins, proposed by Martin Uecker (taking inspiration from glibc's tgmath.h), is:

#define ICE_P(x) (sizeof(int) == sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1)))

如果参数是整数常量表达式,则该宏扩展为值为 1 的整数常量表达式,否则为 0.然而,它依赖于 sizeof(void) 被允许(并且不同于 sizeof(int)),这是一个 GNU C 扩展.

This macro expands into an integer constant expression of value 1 if the argument is an integer constant expression, 0 otherwise. However, it relies on sizeof(void) to be allowed (and different than sizeof(int)), which is a GNU C extension.

是否可以在没有内置函数和不依赖语言扩展的情况下编写这样的宏?如果是,它是否评估其论点?

Is it possible to write such a macro without builtins and without relying on language extensions? If yes, does it evaluate its argument?

有关上述宏的解释,请参阅:Linux 内核的 __is_constexpr 宏

For an explanation of the macro shown above, see instead: Linux Kernel's __is_constexpr Macro

推荐答案

同理,其中?:表达式的类型取决于参数是空指针常量还是普通void *,但使用 <检测类型代码>_通用:

Use the same idea, where the type of a ?: expression depends on whether an argument is a null pointer constant or an ordinary void *, but detect the type with _Generic:

#define ICE_P(x) _Generic((1? (void *) ((x)*0) : (int *) 0), int*: 1, void*: 0)

Ideone 上的演示. _Generic 是 C11 的补充,所以如果你是卡在 C99 或者更早的东西上,你将无法使用它.

Demo on Ideone. _Generic is a C11 addition, so if you're stuck on C99 or something earlier, you won't be able to use it.

此外,还有用于空指针定义的标准链接常量空指针常量与类型交互的方式一个 ?: 表达式:

Also, have standard links for the definition of a null pointer constant and the way null pointer constants interact with the type of a ?: expression:

值为 0 的整数常量表达式,或转换为 void * 类型的此类表达式,称为空指针常量.

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

如果第二个和第三个操作数都是指针,或者一个是空指针常量,另一个是指针,则结果类型是一个指向一个类型的指针,该类型由两个操作数引用的类型的所有类型限定符限定.此外,如果两个操作数都是指向兼容类型或兼容类型的不同限定版本的指针,则结果类型是指向复合类型的适当限定版本的指针;如果一个操作数是空指针常量,则结果具有另一个操作数的类型;否则,一个操作数是指向 void 或 void 的限定版本的指针,在这种情况下,结果类型是指向适当限定版本的 void 的指针.

If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.

这篇关于检测宏中的整数常量表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆