Подтвердить что ты не робот

Ошибка вычисления размера элемента

У меня такая структура (по какой-то причине я не могу использовать массив):

  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. Не имеет значения, где я помещаю объявление enum внутри или вне структуры. Почему компилятор не может принять размер этого membmer?

4b9b3361

Ответ 1

Похоже, ваш компилятор не поддерживает С++ 11, что позволяет использовать Type::member в неоцениваемых выражениях. Вам нужно будет выработать выражение правильного типа, например:

OperatorData* noImpl();

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

Ответ 2

Использовать typedefs:

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

Ответ 3

Я не думаю, что это безопасно; может быть добавлено дополнение между участниками или после них, которое будет включено в 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));

Заметим еще раз, что это также просто приближение. Надеемся, что любое дополнение будет намного меньше, чем сами участники, чтобы их вклад был округлен.

Ответ 4

Нестатический член не может быть доступен с помощью оператора ::.

В С++ 11 вы можете сделать это (быстрая демонстрация):

#include <utility>

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

И в С++ 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() не будет выполнено.

Ответ 5

Сначала вы должны установить правильное выравнивание с помощью компиляторов pragmas (http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx в Visual Studio, http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html в gcc) иначе sizeof(OperatorData) может быть чем угодно.

Затем у вас должен быть экземпляр OperatorData, из которого вы берете записи и используете их в sizeof()

Ответ 6

Это потому, что m_record_0 не является статическим членом struct OperatorData. Это можно сделать только тогда, когда это статический член.

Ответ 7

Создайте объект своей структуры и используйте на нем оператор sizeof().