12

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

  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。我将枚举声明放在结构内部或外部的哪个位置都没有关系。为什么编译器不能接受这个成员的大小?

4

7 回答 7

12

It looks like your compiler doesn't support C++11 that allows the use of Type::member in unevaluated expressions. You'll have to manufacture an expression of the correct type, something like:

OperatorData* noImpl();

enum{fieldsAmount = sizeof(OperatorData) / sizeof(noImpl()->m_record_0)};
于 2012-04-18T10:01:16.163 回答
5

Use typedefs:

typedef char RecordType[RIX_OPERATOR_CONFIG_SIZE];

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

Then:

enum {fieldsAmount = sizeof(OperatorData) / sizeof(RecordType)};
于 2012-04-18T10:01:42.717 回答
4

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

Of course you could use the already-available RIX_OPERATOR_CONFIG_SIZE value to get an approximation:

const size_t num_records = sizeof (OperatorData) / RIX_OPERATOR_CONFIG_SIZE;

assuming it's only used for char arrays, and that it dwarves any padding.

You can also use offsetof(), this has the benefit of including at least padding between the members:

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

Note, again, that this also is just an approximation. Hopefully, any padding will be much smaller than the members themselves so that their contribution will be rounded away.

于 2012-04-18T10:00:21.990 回答
3

A non-static member cannot be accessed using :: operator.

In C++11, you can do this (quick demo):

#include <utility>

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

And in C++03, do this:

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

The type of the expression ((OperatorData*)(0)) is OperatorData*, so I use ((OperatorData*)(0))->m_record_0 to get the size which is roughly equivalent to this:

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

But it is not exactly same, as the above statement will be executed, but the expression in sizeof() will not be executed.

于 2012-04-18T10:01:01.427 回答
2

You first have to set the correct alignment using compiler pragmas ( http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx in Visual Studio, http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html in gcc) otherwise sizeof(OperatorData) may be anything.

Then you have to have an instance of OperatorData from which you pick up the records and use them in sizeof()

于 2012-04-18T10:07:11.020 回答
0

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

于 2012-04-18T09:59:00.610 回答
0

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

于 2012-04-18T09:59:16.463 回答