问题描述
我想让 c 编译器检查简单类型的使用情况。我的首选用法是检查 typedef
,但即使使用 -Wall
和 -Wextra
也没有这样做:
#include <math.h>
#include <stdio.h>
typedef float deg;
typedef float rad;
float sinus( rad angle ) {
return sin( angle );
}
int main() {
deg a = 180;
printf( "The sinus of %g is %g\n",a,sinus(a));
return 0;
}
这可以顺利编译。
所以我正在考虑使用单成员结构:
#include <math.h>
#include <stdio.h>
typedef struct { float value; } deg;
typedef struct { float value; } rad;
float sinus( rad angle ) {
return sin( angle.value );
}
int main() {
deg a = {.value=180};
printf( "The sinus of %g is %g\n",sinus(a));
return 0;
}
这给出了一个彻头彻尾的错误(应该如此)。但是,我想知道性能。如果我更正上述示例,则生成的二进制文件具有相同的大小,无论是否进行优化。但是,生产的组件不同。即使在更复杂的上下文中,编译器能否优化出 struct
?如果没有,是否有另一种方法可以实现原始类型的类型安全?
我正在使用 GCC (9.1.0),但如果有帮助,我会考虑使用 llvm。这应该适用于常见的桌面架构,即 x86、x86_64、ARM。
编辑:我注意到您还可以在上面的示例中使用 union
代替 struct
。这再次产生略有不同的汇编代码,而且我也不清楚真实世界的性能后果。
解决方法
我想让 c 编译器检查简单类型的使用情况。我的首选用法是检查 typedef,但没有这样做
使用 recent GCC 的一种可能方法可能是在 typedef(或 __attribute__
-s)上添加额外的 #pragma
并编写自己的代码GCC plugin 进行检查(可能同时使用 type inference 和 abstract interpretation 技术)
请注意,您想要的功能超出了标准 C 的语义,如定义在例如n2176。
如果允许(并获得资助),我可能会(在 2021 年春季)扩展 Bismon 静态分析器(在此 DRAFT 报告中描述)以实现您的目标。另请参阅 CHARIOT 和 DECODER 项目。给我发电子邮件至 basile.starynkevitch@cea.fr
了解更多信息。
另一种方法是设计您自己的编程语言,并编写您的编译器 generating C code。然后 ACM SIGPLAN 会议是相关的。
或者根据您的需要调整 Frama-C 或 Clang static analyzer。
在所有情况下,都要预算几个月的专业软件工程师劳动力。注意Rice's theorem。
您梦寐以求的检查可以部分自动化,但需要昂贵的开发成本。
您的问题与 dimensional analysis 有关:以米为单位的距离除以以秒为单位的持续时间得出速度。还有单位(角度可以是弧度和度数)
IIRC,一些航天器因为这样的错误而丢失了。