c - 设计时的 C 宏参数测试
问题描述
我需要在设计时(预处理器)进行宏变量检查,更具体地说,该数字适合 24 位。该宏旨在用于 if() 语句,所以我不知道如何测试它。
这是一个 ARM systick 计时器(24 位),很多时候我都忘记了#define 正确的值,尤其是在更改 MCU 时钟时,当然,我的 if() 从未触发,这个愚蠢的错误很难调试。
所以在这个例子中,有一个技巧可以在 PARAMETER > 24 bits 时强制 gcc 出错?
#define PARAMETER 20000000 // over 24 bits, should throw a error at design time
#define MyMacro(var, par) (var > par)
uint32_t variable;
if(MyMacro(variable,PARAMETER))
{
// do something
// do something WRONG because PARAMETER > 24 bits
// Actually this is working as expected, test for < is valid because
// _Static_assert() is check for TRUE condition
// But I am still trying to find a way to combine this in original macro
_Static_assert(PARAMETER < 0xFFFFFF, "Ooopss... ERROR");
}
提前致谢!
解决方案
不幸的是,_Static_assert
在语法上定义为声明,这意味着您不能直接在表达式中使用它。
然而,_Static_assert
无论如何都不需要,因为你可以完美地(没有漂亮的编译时错误报告——但你是一名程序员,你应该能够找出编译时失败一个稍微技术性的编译时错误消息)模仿它
#define static_assert_0expr(Truth) ((int)(0*sizeof(struct { int _ : (Truth)?1:-1; })))
(或等价物)并且您可以放入表达式(甚至是整数常量表达式)没问题:
#define static_assert_0expr(Truth) ((int)(0*sizeof(struct { int _ : (Truth)?1:-1; })))
#define PARAMETER 20000000 // over 24 bits, should throw a error at design time
#define MyMacro(var, par) (static_assert_0expr((par)<0xffffff) + ((var) > (par)))
//or this, but this is won't preserve integer-constant expressions because of the comma:
/*#define MyMacro(var, par) (static_assert_0expr((par)<0xffffff), ((var) > (par)))*/
//alternatively: (static_assert_0expr(assertion) ? (expr) : (expr)) is the most
//general form (though it leads to larger preprocessor expansions, which may worsen debugging experience with cc -E)
#include <stdint.h>
int main()
{
static_assert_0expr(1)+1;
uint32_t variable;
if(MyMacro(variable,PARAMETER))
{
}
}
上面的static_assert_0expr
宏也可以用_Static_assert
:
#define static_assert_0expr(Truth) \
((int)(0*sizeof(struct { int _; _Static_assert(Truth,""); })))
或者您可以将其正文直接粘贴到其中MyMacro
并自定义消息(但我认为_Static_assert
其自定义编译时错误消息具有对 C 的不必要添加,因此不希望使用它)。
推荐阅读
- r - 在反应式上下文中监视目录中文件/文件夹数量的好方法是什么?
- excel - 我只想看到实际的 x 值显示在 Excel 图表的水平轴上(比例与这些值匹配)不让 Excel 进行缩放和标记
- html - 选项卡的 onclick 选项卡内容不完全可见(jquery)
- typescript - 在 vue 3 中从另一个本地项目导入和显示组件
- google-sheets - 谷歌表 - 简单的 importxml 公式不起作用
- scala - SPARK/SCALA 中 oracle RAWTOHEX/HEXTORAW 的等效 API 是什么?
- vb.net - 如果语句没有捕获捕获条件
- php - 为什么我没有从控制器的视图中获取表名?
- css - 在 react.js 中选择时更改字体/按钮的重量
- java - 将 lambda (Object -> Object) 传递给 Java 中的函数