#c #c 11
#c #c 11
Вопрос:
Если существует структура POD с некоторыми переменными-членами, например, такими:
struct foo
{
short a;
int b;
char c[50];
// ...
};
Есть ли способ получить размер переменной-члена в байтах, не создавая объект этого типа?
Я знаю, что это сработает:
foo fooObj;
std::cout << sizeof( fooObj.a ) << std::endl;
std::cout << sizeof( fooObj.b ) << std::endl;
std::cout << sizeof( fooObj.c ) << std::endl;
Будет ли следующее оптимизировано компилятором и предотвратит создание объекта?
std::cout << sizeof( foo().a ) << std::endl;
Комментарии:
1. Если они не являются статическими, я так не думаю…
2. Каковы точные требования? Почему вы не можете использовать информацию о времени компиляции? В моем понимании, C не использует динамическую генерацию классов и манипулирование ими
Ответ №1:
Вы можете сделать это в C 0x:
sizeof(foo::a);
Ответ №2:
5.3.3/1:
Оператор sizeof выдает количество байтов в объектном представлении его операнда. Операндом является либо выражение, которое не вычисляется, либо заключенный в скобки идентификатор типа.
Вышесказанное означает, что следующая конструкция четко определена:
sizeof( ((foo *) 0)->a);
Комментарии:
1. @Martin: Но он пишет макрос, вы бы сказали «Слишком много работы, и это скрывает фактический смысл». : P
2. @Nawaz: Но на основе приведенного выше стандарта. Исходные комментарии OP сохранены,
sizeof(foo().a)
действительны, четко определены, объект не сконструирован, не является уродливым и не требует дополнительной работы с макросом, который может ввести в заблуждение.3. @Martin: Что?
foo()
не создает объект, даже будь это анонимный объект?4. @Nawaz: Нет, не в этом случае, операнд sizeof не вычисляется.
5. @Erik: Потрясающе. Как получилось, что я это пропустил.
Ответ №3:
Вместо этого используйте эту форму: sizeof(foo::a)
.
Ответ №4:
Используйте очевидный:
sizeof( foo::a )
В C sizeof ВСЕГДА вычисляется во время компиляции, поэтому никаких затрат на выполнение не требуется.
Комментарии:
1. Это работает 🙂 он просто ссылается на элемент внутри определения класса.
2. @Nawaz А? Какое отношение к этому имеет static?
3. @unapersson: Вы обращаетесь к
a
тому, который является нестатическим членомfoo
.4. Я должен отметить, что некоторое время назад я переключился на компиляцию своего кода с c 0x. Может быть, нам здесь нужны два тега C ?
5. @Space_C0wb0y Но sizeof( foo::a ) не работает для текущей версии c . Это работает для c 0x
Ответ №5:
C -0x позволяет это сделать:
std::cout << sizeof( foo::a ) << std::endl;
std::cout << sizeof( foo::b ) << std::endl;
std::cout << sizeof( foo::c ) << std::endl;
C -0x позволяет sizeof работать с членами классов без явного объекта.
Статья находится здесь: Расширение sizeof для применения к нестатическим элементам данных без объекта (редакция 1)
Я увидел сообщение об этом выше слишком поздно. Извините.
Ответ №6:
Вы можете создать оболочку макроса из того, что @Erik предложил как:
#define SIZE_OF_MEMBER(cls, member) sizeof( ((cls*)0)->member )
А затем использовать его как:
cout << SIZE_OF_MEMBER(foo, c) << endl;
Вывод:
50
Демонстрация:http://www.ideone.com/ZRiMe
Комментарии:
1. Слишком много работы, и это скрывает фактический смысл. По крайней мере, дайте макросу имя, которое объясняет, что он делает.
2. @Martin: Я не нашел никакого убедительного имени для макроса. Предложите мне один. 🙂
3. SIZE_OF_MEMBER, вот что она сказала.
4. Все еще предстоит много работы. Но, по крайней мере, теперь имя выделяется.
5. используйте: sizeof(foo().a) или sizeof(foo::a)
Ответ №7:
struct foo
{
short a;
int b;
char c[50];
// ...
static const size_t size_a = sizeof(a);
static const size_t size_b = sizeof(b);
static const size_t size_c = sizeof(c);
};
Использование:
foo::size_a
Комментарии:
1. Это сработало бы, но было бы PITA, потому что для этого потребовалось бы добавить 10 дополнительных статических переменных
2.
sizeof
не приводитint
, оно выдаетstd::size_t
.3. @iammilind : К сожалению, я не был отрицательным голосованием. ;-]