在 const 引用中使用静态 constexpr 变量时是否有可能产生错误?

问题描述 投票:0回答:1

我的头文件库需要在 C++14 (g++) 中定义浮点常量。该库包含以下声明:

struct A // POD with constants
{
  static constexpr float a{0.1f};
  // more stuff
}

用户在类似的语句中使用它

void func(const float&);

还有电话

func(A::a);

这会导致链接器错误

my.cpp:(.text+0xaffe): undefined reference to `A::a'

如何更改此设置,以便编译器(而不是链接器)在将 constexpr 作为 const 引用移交的位置创建错误(或至少是警告)?

测试示例

背景信息,在投票前阅读(回答问题不需要):

去年年底,MISRA 编码约定已发布 C++14(安全内容)。因此,尽管可以预见 C++17 很快就会可用,但标准是固定的。通过使用 convert(A::a) 保护常量的使用,可以轻松避免该错误,其中该函数定义为模板 T Convert(T v) {return v;}。这不需要任何符号的定义。对于嵌入式二进制文件的开发,通常会以静态库的形式提供库进行集成,因为没有可以进行地址重定位的绑定程序。人们可以希望运行链接器的测试用例能够检测到该错误。然而,仍然很多时候集成商会出现错误,然后集成商又返回给开发人员。我希望能够通过使用编译器标志之类的东西或使用带有隐式转换运算符的模板结构(据我所知,即使它是内联的,也需要一个自己的符号)来优化它,以报告警告或错误编译时间或完全删除符号的必要性。

c++ g++ c++14
1个回答
0
投票

如果您需要它是 constexpr,您可以将其设为模板参数。自 C++20 起允许使用浮点模板参数:

#include <iostream>

template <float x>
void foo(){
    std::cout << x;
}


int main() {
    constexpr float a = 4.23;
    const float b = 2.1;
    foo<a>(); // ok
    //foo<b>(); // error
}

现场演示.

适用有关浮点值精度的常见注意事项。尽管仅调用函数并使用该值,但这不是问题。只是不要依赖例如

foo<0.3>
foo<0.1 + 0.2>
是相同的函数。

© www.soinside.com 2019 - 2024. All rights reserved.