Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sizeof member computation error

Tags:

c++

I have such a structure (for some reason I cant just use an array):

  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];
  };

And I am trying to calculate amount of fields at compile-time:

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

And the compiler reports such a message:

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

I use keil uVision3 V3.60. It doesn't matter where I place enum declaration inside or outside the structure. Why can't the compiler take size of this membmer?

like image 259
D_E Avatar asked Apr 18 '12 09:04

D_E


3 Answers

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)};
like image 76
CB Bailey Avatar answered Nov 08 '22 07:11

CB Bailey


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)};
like image 24
Cătălin Pitiș Avatar answered Nov 08 '22 05:11

Cătălin Pitiș


I don't think this is safe; there can be padding added between or after the members, which will be included in sizeof (OperatorData) but not in any specific member's size.

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.

like image 29
unwind Avatar answered Nov 08 '22 07:11

unwind