静态整数,编译单元和三元运算符 [英] static ints, compilation units and the ternary operator

查看:61
本文介绍了静态整数,编译单元和三元运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

//SomeCls.h

// SomeCls.h

class SomeCls
    {
    static const int PERIOD_ALARM_NORMAL    =   5;          
    static const int PERIOD_ALARM_THRESH    =   1;          

    void method()
    {
        bool b = true;
        const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
    }

    } obj;

它会建立好的.现在,取出method()实现并将其放置在cpp文件中:

It is going to build ok. Now take out the method() implementation and place it in a cpp file:

 //SomeCls.cpp
#include "SomeCls.h"

void SomeCls::method()
    {
        bool b = true;
        const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
    }

为什么先生.链接器说

未定义对 SomeCls :: PERIOD_ALARM_NORMAL的引用'未定义引用 SomeCls :: PERIOD_ALARM_THRESH'

undefined reference to SomeCls::PERIOD_ALARM_NORMAL' undefined reference toSomeCls::PERIOD_ALARM_THRESH'

?

谢谢

在我看来,在.h内,三元运算符将其静态const int当作rvalue,而在....之外的三元运算符中,将它们视为lvalue并需要定义.这是我从下面的答案中设法理解的内容.对Bada编译器表示敬意(一些eabi linux Thinggie)

It seems to me that that inside .h, the ternary operator takes static const ints it as rvalues but ... outside the decalrative .h, it regards them as lvalue and needs definition. This is what I have managed to understand from the answers below. Kudos to Bada compiler (some eabi linux thinggie)

推荐答案

这是GCC的限制,但完全符合标准.从技术上讲, static const int 仍然是 lvalue .您已经提供了内联值,因此编译器几乎总是将其用作 rvalue .有一个例外.编译器为三元运算符发出的抽象指令查询 lvalues 的地址.因此,您会看到错误.

This is a GCC limitation, but it's completely standard comforming. Technically a static const int is still an lvalue. You've provided the value inline so compiler will almost always use it as an rvalue. There is one exception. The abstract instructions emitted by the compiler for ternary operators queries the address of lvalues. Hence the error you're seeing.

您可以改为使用 enum 解决此问题.或者,如果您使用的是GCC的新版本,则将 constexpr 添加到标准中以解决此确切问题(命名和键入的右值).

You can work around this by using enum instead. Or if you're using a new version of GCC constexpr was added to standard to fix this exact problem (named and typed rvalues).

或者,您可以为链接器提供常量的定义.例如.在您的班级cpp文件中,添加一行,如

Alternatively you can provide the linker with a definition for the constants. E.g. in your classes cpp file add the a line like

// I wish I had constexpr
const int SomeCls::PERIOD_ALARM_NORMAL;
const int SomeCls::PERIOD_ALARM_THRESH;

作为旁注:我是类范围常量的 static const 的坚定支持者.然后,我发现MSVC不允许使用值inline的 static const float .因此,您可以移植到 static const 中的唯一值是整数,在这种情况下, enum 提供所有相同的功能,并保证它们永远不会静默转换为左值.

As a side note: I was a staunch proponent of static const for class scope constants. Then I found out that MSVC doesn't allow for static const float with the value inline. So the only values you can portably put in a static const are integers, in which case enums provide all the same features plus the guarantee that they'll never silently convert to an lvalue.

这篇关于静态整数,编译单元和三元运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆