sizeof成员计算错误

时间:2012-04-18 09:55:30

标签: c++

我有这样的结构(出于某种原因我不能使用数组):

  struct OperatorData 
  {
    char m_record_0[RIX_OPERATOR_CONFIG_SIZE];
    char m_record_1[RIX_OPERATOR_CONFIG_SIZE];
    //....
    char m_record_9[RIX_OPERATOR_CONFIG_SIZE];
  };

我正在尝试在编译时计算字段数量:

enum {fieldsAmount = sizeof(OperatorData) / sizeof(OperatorData::m_record_0)};

编译器会报告这样的消息:

Error:  #245: a nonstatic member reference must be relative to a specific object
  enum{fieldsAmount = sizeof(OperatorData) / sizeof(OperatorData::m_record_0)};
                                                                  ^

我使用keil uVision3 V3.60。 在结构内部或外部放置枚举声明并不重要。 为什么编译器不能占用这个元素的大小?

7 个答案:

答案 0 :(得分:12)

看起来您的编译器不支持允许在未评估的表达式中使用Type::member的C ++ 11。你必须制作一个正确类型的表达式,如:

OperatorData* noImpl();

enum{fieldsAmount = sizeof(OperatorData) / sizeof(noImpl()->m_record_0)};

答案 1 :(得分:5)

使用typedef:

typedef char RecordType[RIX_OPERATOR_CONFIG_SIZE];

struct OperatorData 
{
   RecordType m_record_0;
   RecordType m_record_1;
   //....
   RecordType m_record_9;
};

然后:

enum {fieldsAmount = sizeof(OperatorData) / sizeof(RecordType)};

答案 2 :(得分:4)

我认为这不安全;成员之间或之后可以添加填充,这些填充将包含在sizeof (OperatorData)中,但不包含在任何特定成员的大小中。

当然,您可以使用已有的RIX_OPERATOR_CONFIG_SIZE值来获得近似值:

const size_t num_records = sizeof (OperatorData) / RIX_OPERATOR_CONFIG_SIZE;

假设它仅用于char数组,并且它使任何填充都相形见绌。

您也可以使用offsetof(),这样做的好处是至少包含成员之间的填充:

const size_t num_records = sizeof (OperatorData) /
       (offsetof(OperatorData, m_record_1) - offsetof(OperatorData, m_record_0));

再次注意,这也只是一个近似值。希望任何填充都比成员本身小得多,这样他们的贡献就会消失。

答案 3 :(得分:3)

使用::运算符无法访问非静态成员。

在C ++ 11中,您可以执行此操作(quick demo):

#include <utility>

size = sizeof(OperatorData)/sizeof(std::declval<OperatorData>().m_record_0);

在C ++ 03中,执行此操作:

size = sizeof(OperatorData) / sizeof(((OperatorData*)(0))->m_record_0);

表达式((OperatorData*)(0))的类型为OperatorData*,因此我使用((OperatorData*)(0))->m_record_0来获得与此大致相当的大小:

OperatorData*  od = ((OperatorData*)(0));
size_t size = sizeof(od->m_record_0); 

但它不完全相同,因为上述语句将被执行,但sizeof()中的表达式将不会被执行。

答案 4 :(得分:2)

首先必须使用编译器编译指示(Visual Studio中的http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx,gcc中的http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html)设置正确的对齐方式,否则sizeof(OperatorData)可能是任何内容。

然后你必须有一个OperatorData实例,你可以从中获取记录并在sizeof()

中使用它们

答案 5 :(得分:0)

这是因为m_record_0不是结构OperatorData的静态成员。只有当它是静态成员时才能这样做。

答案 6 :(得分:0)

创建结构的Object并在其上使用sizeof()运算符。