是否有可能区分没有_Generic的相同表示的整数类型?



在标准C语言中,整数类型可能具有相同的大小、对齐方式和表示,但仍然是具有不同转换等级的不同类型。例如x86_64-linux上的unsigned longunsigned long long。使用C11的_Generic特性可以区分这些类型,甚至通过typedef:

#if 0 /* valid shell script */
${CC-cc} -std=c11 -Wall -o "${0%.c}" "$0" && exec "${0%.c}"
#endif
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#if !defined __linux__ || !defined __LP64__
#error wrong platform
#endif
int main(void) {
size_t n;
assert((size_t)-1 == ULONG_MAX && (size_t)-1 == ULLONG_MAX);
assert(sizeof(size_t) == sizeof(unsigned long) &&
sizeof(size_t) == sizeof(unsigned long long));
assert(_Alignof(size_t) == _Alignof(unsigned long) &&
_Alignof(size_t) == _Alignof(unsigned long long));
assert(_Generic(n,
unsigned long long: !"should not be chosen",
unsigned long: "should be chosen"));
return 0;
}

如果类型不同,也可能使程序编译失败,正如您在configure脚本中所希望的那样:

#include <stddef.h>
int main(void) { (void)sizeof((size_t *)0 - (unsigned long long *)0); return 0; }

您是否可以在C11之前检测到差异,而不导致编译失败,并且不诉诸于依赖于编译器的特性(如GNU cpp的__SIZE_TYPE__) ?

您能在C11之前检测到差异而不导致编译失败并且不诉诸于依赖于编译器的特性(如GNU cpp的__SIZE_TYPE__)吗?

在C11之前,标准C没有任何形式的自省。_Generic是第一个针对表达式类型提供条件编译或执行行为的标准特性。

甚至_Generic的用处也有限,因为每个表达式的类型在编译时都是已知的。主要用例是当您在多个不同的上下文中(即通过宏)重用相同的源代码时。您确实可以使用它(在C11和更高版本中)来测试关于类型的某些[静态]断言,但通常最好编写代码,使其不依赖于语言规范不直接支持的类型假设。

在C11之前,您可以测试C数据类型的各种属性,例如存储大小,签名,值位数,甚至对齐要求,但是正如您在问题中观察到的那样,C允许不同类型具有相同的所有这些属性。

相关内容

  • 没有找到相关文章

最新更新