C 通过Typedef定义新类型



我是C 中的新手,我遇到了一个问题,我需要通过我的班级中的Typedef来定义新的数据类型。我班级的.H模块的相关代码片段正在遵循

class Manager
{
  public:
    static const uint8_t NO_BYTES_IN_PACKET;
    static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
    // control packet structure
    typedef union{
        struct{
            uint8_t header[3];                                
            uint8_t payload[NO_PYLD_BYTES_IN_CONTROL_PACKET];  
        }pkt_parts_t;
        uint8_t pkt_array[NO_BYTES_IN_PACKET];
    }control_pkt_u;
  private:
}

我的问题是常数

static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;

在相关的.cpp模块中定义

const uint8_t Manager::NO_BYTES_IN_PACKET = 8;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;

因此,我一直在收到一条错误消息:错误:数组绑定在编译过程中']'']''我的想法是将工会定义转移到.cpp模块中,但我不确定这是否是正确的方法。您有什么意见?谢谢您的任何想法。

如果您不 odr-use 那些 static const int,则无需在.cc文件中定义它们,只需将值放入.h文件中:

class Manager
{
  public:
    static const uint8_t NO_BYTES_IN_PACKET = 8;
    static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
/* .... */
};

但是,如果您使用这些常数,例如采用它们的地址,则需要在.cc文件中定义它们,则.h文件中的类定义保持不变:

const uint8_t Manager::NO_BYTES_IN_PACKET;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET;

编辑:对于评论或其他答案,声称static const int不能用作编译时常数,他们的主张是错误的。

以下引用来自[class.static.data]/3(强调矿山(:

如果非挥发性const静态数据成员是积分或枚举类型,则其在类定义中的声明可以指定一个brace-or-qual-Inialializer,其中每个(分配(表达的每个初始化器条件是常数表达式([Expr.Const](。可以使用ConstexPR规范的类别定义在类型中声明字面类型的静态数据成员;如果是这样,则其声明应指定一个支撑或平等限制器,其中每个初始化器子句(分配表达式(都是恒定的表达式。[注意:在这两种情况下,成员可能以常数表达方式出现。 - end Note] 如果它是ODR使用的,则成员仍应在名称空间范围中定义。([basic.def.odr](和命名空间范围定义不包含初始器。

问题是static const并不意味着它是编译时间常数。作为不是什么地方,可能是程序开始的时间。

您想要的是constexpr,它告诉编译器可以在编译器时间计算,这意味着您的数组大小已很好地定义,并且更清楚地传达了您的意图。

IE

class Manager{
    public:
        constexpr uint8_t NO_BYTES_IN_PACKET = 8;
        ...

另外;它将迫使您解决实际问题,即其他编译单元无法看到常数的大小,因为您未在标题中定义它。

最新更新