Ошибка вычисления размера элемента
У меня такая структура (по какой-то причине я не могу использовать массив):
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?
Ответы
Ответ 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()
.