Как найти длину структуры

struct a
{
    char *c;
    char b;
};

What is sizeof(a)?

GEOCHET's user avatar

GEOCHET

21.1k15 gold badges73 silver badges98 bronze badges

asked Sep 27, 2008 at 4:58

1

#include <stdio.h>

typedef struct { char* c; char b; } a;

int main()
{
    printf("sizeof(a) == %d", sizeof(a));
}

I get “sizeof(a) == 8”, on a 32-bit machine. The total size of the structure will depend on the packing: In my case, the default packing is 4, so ‘c’ takes 4 bytes, ‘b’ takes one byte, leaving 3 padding bytes to bring it to the next multiple of 4: 8. If you want to alter this packing, most compilers have a way to alter it, for example, on MSVC:

#pragma pack(1)
typedef struct { char* c; char b; } a;

gives sizeof(a) == 5. If you do this, be careful to reset the packing before any library headers!

answered Sep 27, 2008 at 5:13

Simon Buchan's user avatar

Simon BuchanSimon Buchan

12.6k2 gold badges48 silver badges55 bronze badges

4

Contrary to what some of the other answers have said, on most systems, in the absence of a pragma or compiler option, the size of the structure will be at least 6 bytes and, on most 32-bit systems, 8 bytes. For 64-bit systems, the size could easily be 16 bytes. Alignment does come into play; always. The sizeof a single struct has to be such that an array of those sizes can be allocated and the individual members of the array are sufficiently aligned for the processor in question. Consequently, if the size of the struct was 5 as others have hypothesized, then an array of two such structures would be 10 bytes long, and the char pointer in the second array member would be aligned on an odd byte, which would (on most processors) cause a major bottleneck in the performance.

answered Sep 27, 2008 at 5:10

Jonathan Leffler's user avatar

Jonathan LefflerJonathan Leffler

726k140 gold badges899 silver badges1275 bronze badges

2

If you want to manually count it, the size of a struct is just the size of each of its data members after accounting for alignment. There’s no magic overhead bytes for a struct.

answered Sep 27, 2008 at 5:21

Jeff Hubbard's user avatar

Jeff HubbardJeff Hubbard

9,7723 gold badges30 silver badges28 bronze badges

The exact value is sizeof(a).
You might also take a risk and assume that it is in this case no less than 2 and no greater than 16.

answered Sep 27, 2008 at 5:09

eugensk's user avatar

eugenskeugensk

1,8621 gold badge14 silver badges20 bronze badges

1

This will vary depending on your architecture and how it treats basic data types. It will also depend on whether the system requires natural alignment.

answered Sep 27, 2008 at 5:04

mdec's user avatar

mdecmdec

5,0624 gold badges25 silver badges26 bronze badges

I assume you mean struct and not strict, but on a 32-bit system it’ll be either 5 or 8 bytes, depending on if the compiler is padding the struct.

answered Sep 27, 2008 at 5:00

Serafina Brocious's user avatar

Serafina BrociousSerafina Brocious

30.3k11 gold badges89 silver badges114 bronze badges

I suspect you mean ‘struct’, not ‘strict’, and ‘char’ instead of ‘Char’.

The size will be implementation dependent. On most 32-bit systems, it will probably be 5 — 4 bytes for the pointer, one for the char. I don’t believe alignment will come into play here. If you swapped ‘c’ and ‘b’, however, the size may grow to 8 bytes.

Ok, I tried it out (g++ 4.2.3, with -g option) and I get 8.

answered Sep 27, 2008 at 5:02

Fred Larson's user avatar

Fred LarsonFred Larson

60.6k16 gold badges112 silver badges174 bronze badges

1

The sizeof the structure should be 8 bytes on a 32 bit system, so that the size of the structure becomes multiple of 2. This makes individual structures available at the correct byte boundaries when an array of structures is declared. This is achieved by padding the structure with 3 bytes at the end.

If the structure had the pointer declared after the char, it would still be 8 bytes in size
but the 3 byte padding would have been added to keep the pointer (which is a 4 byte element) aligned at a 4 byte address boundary.

The rule of thumb is that elements should be at an offset which is the multiple of their byte size and the structure itself should be of a size which is a multiple of 2.

Jonathan Leffler's user avatar

answered Sep 27, 2008 at 5:17

computinglife's user avatar

computinglifecomputinglife

4,3131 gold badge21 silver badges17 bronze badges

1

struct a
{
    char *c;
    char b;
};

What is sizeof(a)?

GEOCHET's user avatar

GEOCHET

21.1k15 gold badges73 silver badges98 bronze badges

asked Sep 27, 2008 at 4:58

1

#include <stdio.h>

typedef struct { char* c; char b; } a;

int main()
{
    printf("sizeof(a) == %d", sizeof(a));
}

I get “sizeof(a) == 8”, on a 32-bit machine. The total size of the structure will depend on the packing: In my case, the default packing is 4, so ‘c’ takes 4 bytes, ‘b’ takes one byte, leaving 3 padding bytes to bring it to the next multiple of 4: 8. If you want to alter this packing, most compilers have a way to alter it, for example, on MSVC:

#pragma pack(1)
typedef struct { char* c; char b; } a;

gives sizeof(a) == 5. If you do this, be careful to reset the packing before any library headers!

answered Sep 27, 2008 at 5:13

Simon Buchan's user avatar

Simon BuchanSimon Buchan

12.6k2 gold badges48 silver badges55 bronze badges

4

Contrary to what some of the other answers have said, on most systems, in the absence of a pragma or compiler option, the size of the structure will be at least 6 bytes and, on most 32-bit systems, 8 bytes. For 64-bit systems, the size could easily be 16 bytes. Alignment does come into play; always. The sizeof a single struct has to be such that an array of those sizes can be allocated and the individual members of the array are sufficiently aligned for the processor in question. Consequently, if the size of the struct was 5 as others have hypothesized, then an array of two such structures would be 10 bytes long, and the char pointer in the second array member would be aligned on an odd byte, which would (on most processors) cause a major bottleneck in the performance.

answered Sep 27, 2008 at 5:10

Jonathan Leffler's user avatar

Jonathan LefflerJonathan Leffler

726k140 gold badges899 silver badges1275 bronze badges

2

If you want to manually count it, the size of a struct is just the size of each of its data members after accounting for alignment. There’s no magic overhead bytes for a struct.

answered Sep 27, 2008 at 5:21

Jeff Hubbard's user avatar

Jeff HubbardJeff Hubbard

9,7723 gold badges30 silver badges28 bronze badges

The exact value is sizeof(a).
You might also take a risk and assume that it is in this case no less than 2 and no greater than 16.

answered Sep 27, 2008 at 5:09

eugensk's user avatar

eugenskeugensk

1,8621 gold badge14 silver badges20 bronze badges

1

This will vary depending on your architecture and how it treats basic data types. It will also depend on whether the system requires natural alignment.

answered Sep 27, 2008 at 5:04

mdec's user avatar

mdecmdec

5,0624 gold badges25 silver badges26 bronze badges

I assume you mean struct and not strict, but on a 32-bit system it’ll be either 5 or 8 bytes, depending on if the compiler is padding the struct.

answered Sep 27, 2008 at 5:00

Serafina Brocious's user avatar

Serafina BrociousSerafina Brocious

30.3k11 gold badges89 silver badges114 bronze badges

I suspect you mean ‘struct’, not ‘strict’, and ‘char’ instead of ‘Char’.

The size will be implementation dependent. On most 32-bit systems, it will probably be 5 — 4 bytes for the pointer, one for the char. I don’t believe alignment will come into play here. If you swapped ‘c’ and ‘b’, however, the size may grow to 8 bytes.

Ok, I tried it out (g++ 4.2.3, with -g option) and I get 8.

answered Sep 27, 2008 at 5:02

Fred Larson's user avatar

Fred LarsonFred Larson

60.6k16 gold badges112 silver badges174 bronze badges

1

The sizeof the structure should be 8 bytes on a 32 bit system, so that the size of the structure becomes multiple of 2. This makes individual structures available at the correct byte boundaries when an array of structures is declared. This is achieved by padding the structure with 3 bytes at the end.

If the structure had the pointer declared after the char, it would still be 8 bytes in size
but the 3 byte padding would have been added to keep the pointer (which is a 4 byte element) aligned at a 4 byte address boundary.

The rule of thumb is that elements should be at an offset which is the multiple of their byte size and the structure itself should be of a size which is a multiple of 2.

Jonathan Leffler's user avatar

answered Sep 27, 2008 at 5:17

computinglife's user avatar

computinglifecomputinglife

4,3131 gold badge21 silver badges17 bronze badges

1


Содержание

  • 1. Какое назначение операции sizeof в программах на C++?
  • 2. Примеры использования операции sizeof для базовых типов и числовых значений
  • 3. Как определить размер структурной переменной? Пример
  • 4. Как определить размер массива чисел? Пример
  • 5. Как определить размер массива структур? Пример
  • 6. Как определить размер объекта (экземпляра) класса? Пример
  • 7. Как определить размер массива объектов класса? Пример
  • 8. Какой общий вид в программе имеет тернарная операция ? : ?
  • 9. Примеры использования операции ? :
  • Связанные темы

Поиск на других ресурсах:

1. Какое назначение операции sizeof в программах на C++?

Операция sizeof предназначена для определения размера типа данных, переменной базового типа, переменной структурного типа, числового значения, строчного значения и т.п.

Операция sizeof есть полезной в случаях, когда необходимо динамически выделять память для переменных. В этом случае нужно знать объем памяти, которую занимает объект того или другого типа.

Общий вид операции sizeof:

sizeof(тип_или_переменная)

где

  • тип_или_переменная – название типа данных или переменной (объекта), которая используется на данный момент в программе.

2. Примеры использования операции sizeof для базовых типов и числовых значений

В приведенном ниже фрагменте кода приведен пример определения размера переменной базового типа, числового значения, строчного значения или результата выражения.

// операция sizeof
int a;
short int b;
float x;
double y;
long double z;
int size;

size = sizeof(b); // size = 2
size = sizeof(int); // size = 4
size = sizeof(a); // size = 4
size = sizeof(x); // size = 4
size = sizeof(double); // size = 8
size = sizeof(z); // size = 8
size = sizeof(long double);
size = sizeof(bool); // size = 1
size = sizeof(true); // size = 1
size = sizeof(28); // size = 4 - как тип int
size = sizeof(9.8 + 5); // size = 8 - как тип double
size = sizeof("Hello world!"); // size = 13
size = sizeof('n'); // size = 1

 

3. Как определить размер структурной переменной? Пример

Пусть задана структурная переменная, описывающая данные о студенте. Шаблон структуры описывается в отдельном файле «MyStruct_Student.h»:

struct Student
{
    char name[70];
    int age;
    char address[100];
};

Тогда, чтобы определить объем памяти, который выделяется для переменной типа struct Student, можно написать следующий программный код:

#include "MyStruct_Student.h"

...

// определение размера структурной переменной
int size;
Student ST;

size = sizeof(struct Student); // size = 176
size = sizeof(ST); // size = 176

...

4. Как определить размер массива чисел? Пример
// определение размера массива
int A[100]; // массив из 100 целых чисел
float X[200]; // массив из 200 вещественных чисел
int size;

size = sizeof(A); // size = 4 * 100 = 400
size = sizeof(X); // size = 4 * 200 = 800



5. Как определить размер массива структур? Пример

Пусть задана структурная переменная, описывающая данные о студенте. Шаблон структуры описывается в отдельном файле «MyStruct_Student.h»:

struct Student
{
    char name[70];
    int age;
    char address[100];
};

Программный код, который определяет размер массива из 100 структурных переменных типа Student, будет иметь следующий вид:

#include "MyStruct_Student.h"

...

// определение размера массива структур
Student A[100]; // массив из 100 структур типа Student
int size;
size = sizeof(A); // size = 176 * 100 = 17600

6. Как определить размер объекта (экземпляра) класса? Пример

Пусть в модуле «MyClass.h» описывается класс с именем MyPoint:

class MyPoint
{
    private: int x, y;

    public:
        int GetX(void)
        {
            return x;
        }

        int GetY(void)
        {
            return y;
        }

        void SetXY(int nx, int ny)
        {
            x = nx;
            y = ny;
            return;
        }
};

Чтобы определить размер памяти, которая выделяется для объекта этого класса, нужно написать такой программный код:

#include "MyClass.h"

...

// размер объекта класса
MyPoint P1;
int size;

size = sizeof(P1); // size = 8
size = sizeof(MyPoint); // size = 8

...

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

7. Как определить размер массива объектов класса? Пример

Пусть в модуле «MyClass.h» описывается класс с именем MyPoint:

class MyPoint
{
    private: int x, y;

    public:
        int GetX(void)
        {
            return x;
        }

        int GetY(void)
        {
            return y;
        }

        void SetXY(int nx, int ny)
        {
            x = nx;
            y = ny;
            return;
        }
};

Тогда, фрагмент программного кода, который определяет размер массива из 20 объектов класса MyPoint, будет иметь вид:

#include "MyClass.h"

...

// размер массива объектов класса
MyPoint P1[20];
int size;

size = sizeof(P1); // size = 8 * 20 = 160

...

8. Какой общий вид в программе имеет тернарная операция ? : ?

Тернарная операция ? : может заменять оператор условного перехода if … else. Общий вид операции ? : следующий:

выражение1 ? выражение2 : выражение3

где

  • выражение1 – любое логическое выражение, результатом которого есть значение true или false;
  • выражение2 – выражение, которое будет вычисляться, если значение выражение1 = true;
  • выражение3 – выражение, которое будет вычисяться, если значение выражение1 = false.

9. Примеры использования операции ? :

В нижеследующем фрагменте кода вычисляется минимальное значение между двумя переменными a и b:

// операция ? :
// минимальное значение между двумя числами
int a, b;
int min;

a = 15;
b = 8;
min = a > b ? b : a; // min = 8


Связанные темы

  • Оператор условного перехода if
  • Оператор выбора switch
  • Операторы инкремента (++) и декремента (— —). Составные операторы присваивания (+=, -= …)
  • Таблица приоритетности операций


Тамика

Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

1

Размер структуры

30.11.2016, 15:52. Показов 18870. Ответов 19

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Всем доброго дня!

Не могу понять… Вот код.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct T
{
    char i;
    int a;
    int b;
    int c;
    char j;
};
 
int main()
{
    T t;
    std::cout << sizeof(T);
    system("pause>nul");
}

Выводит размер структуры как 20… Почему 20? Почему не 17?..

Заранее спасибо!



1



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

30.11.2016, 15:52

19

4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

30.11.2016, 15:55

2

Мобыть выравнивание лесов/полей?



1



Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 15:57

 [ТС]

3

Цитата
Сообщение от _Ivana
Посмотреть сообщение

Мобыть выравнивание лесов/полей?

Так а как оно происходит?



0



4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

30.11.2016, 16:00

4

Я не спец, но думаю, как компилятор на память положит. Может есть какие прагмы чтобы влиять на его поведение в этих случаях. Можно погуглить, начав с “выравнивание полей структур”.

Может у вас 32-разрядная система и компилятор под чары в структурах выделяет размер регистра – 4 байта.



1



Модератор

Эксперт С++

13099 / 10371 / 6206

Регистрация: 18.12.2011

Сообщений: 27,733

30.11.2016, 16:02

5

Выравнивание идет на границы 32 битного слова.
Поэтому после каждого из char останется по 3 байта.
Итого: (1+3)+3*4+(1+3)=20 байт.



1



Тамика

Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 16:06

 [ТС]

6

zss, то есть, любой тип приводится к 4-м?
Все, что меньше 4-х:

C++
1
char x[3];

например.

C++
1
short x;

тоже



0



4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

30.11.2016, 16:10

7

Имхо к длине машинного слова данной архитектуры. В вашем случае это 4 байта.



1



Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 16:13

 [ТС]

8

_Ivana, zss, дошло, спасибо!



0



4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

30.11.2016, 16:18

9

Тамика, раз пошла такая пьянка – попробуйте запилить структуру с 4 чарами подряд и двумя интами и посмотрите ее размер. А потом погуглите какую-нибудь packed – прагму или что там бывает, чтобы добиться ужатия первых четырех чаров в одно 32-битное слово.



1



Тамика

Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 16:19

 [ТС]

10

Практика подтвердила!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct T
{
    short int i;
    int a = 66;
    int b = 77;
    int c = 88;
    char j;
};
 
void show(const char* aT, size_t size)
{
    for (int i = 0; i < size; ++i)
        std::cout << "i " << static_cast<int>(aT[i]) << "n";
}
 
int main()
{
    T t;
    show(static_cast<char*>(static_cast<void*>(&t)), sizeof(t));
    system("pause>nul");
}

Добавлено через 33 секунды

Цитата
Сообщение от _Ivana
Посмотреть сообщение

packed – прагму

Простите, но… Энто што?..



0



4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

30.11.2016, 16:21

11

Это я так называю любые волшебные мутаборы, которые могут указать компилятору определенное поведение, например ужимать/паковать поля структур для уменьшения размера памяти или транжирить байты ради скорости доступа.



0



Тамика

Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 16:21

 [ТС]

12

_Ivana, кажется, оно само это делает…

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct T
{
    char i = 0;
    char j = 0;
    char g = 0;
    char h = 0;
    int a = 66;
    int b = 77;
};
 
void show(const char* aT, size_t size)
{
    for (int i = 0; i < size; ++i)
        std::cout << "i " << static_cast<int>(aT[i]) << "n";
}
 
int main()
{
    T t;
    show(static_cast<char*>(static_cast<void*>(&t)), sizeof(t));
    system("pause>nul");
}

Вы ведь это имели в виду?



0



17406 / 9244 / 2257

Регистрация: 30.01.2014

Сообщений: 16,159

30.11.2016, 16:22

13



2



4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

30.11.2016, 16:25

14

Цитата
Сообщение от Тамика
Посмотреть сообщение

_Ivana, кажется, оно само это делает…

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

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



0



17406 / 9244 / 2257

Регистрация: 30.01.2014

Сообщений: 16,159

30.11.2016, 16:30

15

Цитата
Сообщение от Тамика
Посмотреть сообщение

кажется, оно само это делает…

Не оно само, а ты сама
Ты же сама расположила данные в структуре в оптимальном (для твоей платформы) порядке.
А отключение выравнивания – это другое, это если ты данные расположила не в оптимальном порядке, но выравнивать компилятор их все равно не будет. Этим обычно пользуются для формирования всякого разного рода пакетов или заголовков, предназначенных для передачи по сети, записи в файлы и т.п. Есть и обратная сторона медали – прямой доступ к невыравненным данным обычно медленее, а на некоторых аппаратных платформах в принципе невозможен (будет аппаратное исключение). Поэтому лучше этим не баловаться без нужды



1



Тамика

Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 16:34

 [ТС]

16

DrOffset, а я пробовала и с трёмя чариками, и с двумя, и с одним.

А вот такая штука опять меня запутала… Почему если инт первый, то под чар выделяется 4 байта. Если чар один и первый – 1 байт?.. Расположение на позицию кратную 4 тут не котируется, потому что инт первый.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct T1
{
    int c = 88;
    char j = 0;
};
 
struct T2
{
    char i = 0;
};
 
void show(const char* aT, size_t size)
{
    std::cout << "nNEWn";
    for (int i = 0; i < size; ++i)
        std::cout << i << " " << static_cast<int>(aT[i]) << "n";
}
 
int main()
{
    T1 t1;
    T2 t2;
    show(static_cast<char*>(static_cast<void*>(&t1)), sizeof(t1));
    show(static_cast<char*>(static_cast<void*>(&t2)), sizeof(t2));
    system("pause>nul");
}



0



17406 / 9244 / 2257

Регистрация: 30.01.2014

Сообщений: 16,159

30.11.2016, 16:57

17

Цитата
Сообщение от Тамика
Посмотреть сообщение

А вот такая штука опять меня запутала… Почему если инт первый, то под чар выделяется 4 байта. Если чар один и первый – 1 байт?.. Расположение на позицию кратную 4 тут не котируется, потому что инт первый

Потому что выравнивание зависит от типа, а относится к адресу.
Может быть проще будет пользоваться вот таким более строгим определением:
Адреса всех данных размером 2n байт при n >= размеру машинного слова должны делиться на 2(размер машинного слова).

Добавлено через 4 минуты
Тамика, вот хороший материал по теме: http://konishchevdmitry.blogsp… -post.html



1



Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 17:01

 [ТС]

18

DrOffset, получается, у меня машинное слово это 4?



0



17406 / 9244 / 2257

Регистрация: 30.01.2014

Сообщений: 16,159

30.11.2016, 17:04

19

Цитата
Сообщение от Тамика
Посмотреть сообщение

у меня машинное слово это 4?

Да.



1



Котовчанин

942 / 482 / 200

Регистрация: 16.02.2010

Сообщений: 3,338

Записей в блоге: 37

30.11.2016, 17:05

 [ТС]

20

DrOffset, спасиииибо



0



берёшь и получаешь

Harald ★★★★★

(08.09.17 14:54:08 MSK)

  • Ссылка

struct st st;
sizeof(st.fld1);

?

flyshoot

(08.09.17 14:55:35 MSK)



Последнее исправление: flyshoot 08.09.17 14:56:51 MSK
(всего

исправлений: 1)

  • Ссылка

sizeof(((struct st *)(0))->fld1))

anonymous

(08.09.17 14:57:16 MSK)

  • Ссылка

На си

    struct st* v; 
    size_t s = sizeof(v->fld1)

На с++11

   size_t s = sizeof(std::declval<st>().fld1);

Dudraug ★★★★★

(08.09.17 14:58:49 MSK)

  • Показать ответы
  • Ссылка

Ответ на:

комментарий
от Dudraug 08.09.17 14:58:49 MSK

Ответ на:

комментарий
от normann 08.09.17 15:04:02 MSK

Ответ на:

комментарий
от Dudraug 08.09.17 14:58:49 MSK

В последнем варианте наверное будет более корректно использовать decltype вместо sizeof.
Но так как вопрос все равно о си, то юзай первый вариант или что-то в этом роде.

Dudraug ★★★★★

(08.09.17 15:07:56 MSK)



Последнее исправление: Dudraug 08.09.17 15:08:24 MSK
(всего

исправлений: 1)

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от Dudraug 08.09.17 15:04:36 MSK

Ну да, сглупил. Всем откликнувшимся спасибо.

normann ★★

(08.09.17 15:33:48 MSK)



Последнее исправление: normann 08.09.17 15:34:04 MSK
(всего

исправлений: 1)

  • Ссылка

Ответ на:

комментарий
от Dudraug 08.09.17 15:07:56 MSK

decltype вместо sizeof

Не вместо, а вместе. Весь день какую-то дичь выдаю=)

Dudraug ★★★★★

(08.09.17 16:20:08 MSK)

  • Ссылка

Ответ на:

комментарий
от Dudraug 08.09.17 14:58:49 MSK

Ответ на:

комментарий
от normann 08.09.17 15:04:02 MSK

Ответ на:

комментарий
от utf8nowhere 08.09.17 16:38:35 MSK

Ответ на:

комментарий
от Dudraug 08.09.17 17:30:30 MSK

Ну да, пожалуй.

Да ну, хипстерство… Если уж так нужно узнать, то нехай развертывает до стандартных типов, а когда получится ровно то, что в примере топика, то есть long, то уж sizeof этого то узнать можно многими способами.

Если кому интересно, то кроскомпиляторный метод определения размера типа заключается в попытке скомпилить: switch(sizeof(TYPE)) { case 4: break; case sizeof(TYPE): break; } Как ругнётся, значить угадали :))

vodz ★★★★★

(08.09.17 18:02:56 MSK)

  • Ссылка

Ответ на:

комментарий
от utf8nowhere 08.09.17 16:38:35 MSK

Ответ на:

комментарий
от utf8nowhere 08.09.17 16:41:20 MSK

Ответ на:

комментарий
от Sorcerer 11.09.17 21:11:37 MSK

Ответ на:

комментарий
от DELIRIUM 09.09.17 04:35:03 MSK

изобретает sizeof?

Кстати, интересная тема: изобрести sizeof. У меня получилось так:

#include <stdio.h>

struct st {
	long fld1;
};

#define sizeof_field(type, field) 
    ((size_t)((char *)(&((type *)0)->field + 1) - (char *)&((type *)0)->field))

const size_t sz = sizeof_field(struct st, fld1);

int main(void) {
	printf("%zun", sz);
}

Интересно, что здесь может пойти не так.

i-rinat ★★★★★

(12.09.17 00:34:00 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от i-rinat 12.09.17 00:34:00 MSK

Интересно, что здесь может пойти не так.

6.5.3.2 (Address and indirection operators), параграф 4

The unary * operator denotes indirection. If the operand points to a function, the result is
a function designator; if it points to an object, the result is an lvalue designating the
object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an
invalid value has been assigned to the pointer, the behavior of the unary * operator is
undefined.(сноска)

В сноске написано:
Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an
address inappropriately aligned for the type of object pointed to, and the address of an object after the
end of its lifetime.

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от utf8nowhere 12.09.17 00:42:46 MSK

Ответ на:

комментарий
от i-rinat 12.09.17 00:47:38 MSK

Ответ на:

комментарий
от utf8nowhere 12.09.17 00:50:51 MSK

Ответ на:

комментарий
от i-rinat 12.09.17 01:05:10 MSK

Ответ на:

комментарий
от utf8nowhere 12.09.17 00:22:20 MSK

Да, действительно, вне функции тоже можно. Но формально будет создаваться глобальный безымянный объект, к которому никто уже обратиться не сможет.

Sorcerer ★★★★★

(12.09.17 06:44:55 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от Sorcerer 12.09.17 06:44:55 MSK

Но формально будет создаваться глобальный безымянный объект, к которому никто уже обратиться не сможет.

С чего это будет создаваться какой-то объект?

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от utf8nowhere 12.09.17 07:30:19 MSK

The value of the compound literal is that of an unnamed object initialized by the
initializer list. If the compound literal occurs outside the body of a function, the object
has static storage duration; otherwise, it has automatic storage duration associated with
the enclosing block.

По факту оптимизатор может и не будет создавать объект, но конструкция с кастом NULL к указателю на структуру как-то надежней выглядит.

Sorcerer ★★★★★

(12.09.17 07:35:22 MSK)



Последнее исправление: Sorcerer 12.09.17 07:38:25 MSK
(всего

исправлений: 1)

  • Показать ответы
  • Ссылка

Ответ на:

комментарий
от Sorcerer 12.09.17 07:35:22 MSK

The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type. The size is determined from the type of
the operand. The result is an integer. If the type of the operand is a variable length array
type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
integer constant.

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от utf8nowhere 12.09.17 07:38:41 MSK

Ответ на:

комментарий
от Sorcerer 12.09.17 07:35:22 MSK

но конструкция с кастом NULL к указателю на структуру как-то надежней выглядит.

Если с точки зрения независимости от GNU-плюшек — то да, надёжнее.

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от utf8nowhere 12.09.17 22:13:33 MSK

Почему GNU? Это же C99, только проинициализировать надо нулём: sizeof((struct st){0}.fld1)

Sorcerer ★★★★★

(12.09.17 23:01:27 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от Sorcerer 12.09.17 23:01:27 MSK

Почему GNU? Это же C99, только проинициализировать надо

А если не инициализировать — то GNU.

  • Ссылка

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.

Добавить комментарий