我正在嵌入式系统上运行C语言,并且我想确保某个 #define 的值等于特定的值。如果不是,我希望编译器失败并停止继续执行。
我的代码目前看起来像这样:
typedef uint32_t TickType_t; //I can NOT change/modify this typedef
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) //I can NOT change/modify this macro, it's autogenerated
我正在尝试在我的代码中执行以下操作:
#if(1000 != configTICK_RATE_HZ)
#error "configTICK_RATE_HZ is not 1000Hz!"
#endif
在编译时遇到错误,因为 #if 不喜欢看到类型转换(编译器不知道 typedef)。我找到了一个关于如何剥离/删除类型转换的 stackoverflow 讨论(link),其中有一个非常有创意的答案,但它还不太适用于我,因为我认为我需要在使用那个有创意的解决方案之前先删除原始宏中最外层的括号。
换句话说,我想让这个 预处理器 输出:
#if(1000 != configTICK_RATE_HZ )
看起来像这样:
#if(1000 != 1000)
而不是像这样:
#if(1000 != ( ( TickType_t ) 1000 ) )
如果需要中间宏,我不介意,但我不能更改原始的“configTICK_RATE_HZ”定义或 TickType_t 的 typedef。
这是一些最小可复现代码(涵盖我遇到的相同问题的类似问题)。下面的代码失败,因为它不喜欢宏中的类型转换或最外层的括号。
#include <stdio.h>
#define FREQ_HZ ((int)10) //Can not modify this definition
#if( 10 != FREQ_HZ )
#error "Bad frequency value"
#endif
int main(void)
{
printf("Hello world\n");
}
static_assert
的作用。如果条件为假,编译器将生成一个包含给定文本的错误。 - dbush_Static_assert(1000 == configTICK_RATE_HZ, "configTICK_RATE_HZ不是1000Hz!");
- AamerAirlinesstatic_assert
是_Static_assert
的宏。如果你包含了#include <assert.h>
,那么这个宏应该是可用的。 - dbush#include <assert.h>
就可以让static_assert
正常工作了。我注意到一些小的奇怪行为:当条件失败时(例如configTICK_RATE_HZ不是1000),编译器会失败,但它不会打印所需的错误消息。相反,它显示了一个不同的错误:“数组的大小必须大于零”。这很小而且对我来说不是问题,所以我不太在意修复它。谢谢! - AamerAirlinesstatic_assert
将在 C23 中成为一个正式的关键字,并且字符串字面值参数将变为可选。 - Lundin