【问题标题】:How to use const int in _Static_assert?如何在 _Static_assert 中使用 const int?
【发布时间】:2016-02-21 17:52:30
【问题描述】:

前言:我想静态检查C程序中结构成员的数量,所以我创建了两个宏,每个宏都创建常量int,将__LINE__存储到变量中:

 #include <stdio.h>
 #include <string.h>
 #define BEGIN(log) const int __##log##_begin = __LINE__;
 #define END(log) const int __##log##_end = __LINE__;
 BEGIN(TEST);
 struct TEST {
    int t1;
    int t2;
    float t3;
    int t4;
    int t5;
    int t6;
 };
 END(TEST)

 main()
 {
    static_assert(__TEST_end - __TEST_begin  == 6 + 3, "not_equal");
 }

当我使用带有 -std=c++11 选项 (c++ test.cpp -std=c++11) 的 C++ 编译器时,它可以正常工作,但是相同的代码(将 static_assert 替换为 _Static_assert)不能在 C(gcc 版本 4.8.4)中工作时会出现奇怪的错误,因为可以在编译时评估此表达式:

test.c:在函数“main”中:test.c:18:17:错误:静态表达式 断言不是常量 _Static_assert(__TEST_end - __TEST_begin == 6 + 4, "not_equal");

如何修复此错误或实现 C 中的原始目标?

【问题讨论】:

  • 提示:如果您包含 assert.h,您可以使用宏 static_assert 扩展为 C 关键字 _Static_assert。对 C++ 兼容性很有用。
  • @NaCl:当我将变量声明为constexpr 时,编译器会产生更多错误。
  • @Scipio: constexpr 是 C++11 关键字,在 C11 中不起作用。在不相关的说明中,您可能想查看 DMS,这是 StackOverflow 用户 Ira Baxter 制作的工具

标签: c gcc c11


【解决方案1】:

在 C 中,即使使用 const 定义的变量也不是常量表达式。 _Static_assert 要求它的第一个参数是一个常量表达式。因此,可以在 C++ 中完成的相同事情在 C 中却无法完成。

您可以改为进行运行时检查;使用断言。

请注意,此方法无法防止程序员在同一行中键入两个成员或使用相同类型的多个单行声明,或添加空行(或注释)。与其强迫程序员遵循字符串编码模式,只是为了让这个断言能够捕获错误,不如简单地要求程序员定义正确数量的成员,这样就不太容易出错。严格来说更好,因为无论哪种方式都可以使无法检测到的错误,但至少不必担心严格的编码模式。

【讨论】:

  • 我不能使用断言,因为这段代码是在嵌入式硬件上执行的。这些结构(有几十个)用于记录代码,它在 c 字符串中描述结构的成员(就像上面“llflll”示例中的这个)。这种描述中的错误只有在一些手动操作后才能发现,这比静态检查和受限编码模式更糟糕。无论如何,如果真的不可能对结构的成员数进行静态检查,我会接受你的回答,认为这是最有帮助的。
  • @Scipio 其实这比较容易。只需在构建代码时包含另一个步骤。使用自定义程序解析源代码,该程序计算成员并将信息输出到您想要的任何位置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2010-11-11
相关资源
最近更新 更多