Есть ли ограничения по размеру для C-структур? - PullRequest
13 голосов
/ 11 октября 2011

Есть ли ограничения по размеру для структур C?

Ответы [ 3 ]

12 голосов
/ 11 октября 2011

Из стандарта C:

5.2.4.1 Пределы перевода

1 Реализация должна иметь возможность переводить и выполнять по крайней мере одну программу, которая содержиткак минимум один экземпляр каждого из следующих ограничений:

... - 65535 байт в объекте (только в размещенной среде)
... - 1023 члена в одной структуре или объединении
... - 63 уровня вложенных определений структуры или объединения в одном списке struct-объявление ... 13) Реализации должны по возможности избегать наложения фиксированных ограничений на перевод.

Кроме этого,верхняя граница равна SIZE_MAX (максимальное значение для size_t).

6 голосов
/ 11 октября 2011

Поскольку оператор sizeof дает результат типа size_t, предел должен быть SIZE_MAX.

. Вы можете определить значение SIZE_MAX следующим образом:

#include <stdint.h>
#include <stdio.h>

int main (void) {
  printf("%zu", SIZE_MAX);
  return 0;
}

Это то, что должен разрешать компилятор.То, что позволяет среда выполнения, - это другая история.

Объявление объекта аналогичного размера в стеке (локально) на практике не будет работать, поскольку стек, вероятно, намного, намного меньше, чем SIZE_MAX.

* 1014.* Наличие такого объекта в глобальном масштабе может привести к жалобам исполняемого загрузчика при запуске программы.
2 голосов

Эмпирический анализ

На практике такие имплантации, как GCC, допускают только структуры, меньшие size_t, возможно связанные PTRDIFF_MAX. Смотрите также: Какой максимальный размер массива в C?

Использование:

 for i in `seq 32`; do printf "typedef struct { S$i x; S$i y; } S$(($i+1));\n"; done

Составляем программу:

#include <stdint.h>
#include <stdio.h>

typedef struct { uint8_t i; } S0;
typedef struct { S0 x; S0 y; } S1;
typedef struct { S1 x; S1 y; } S2;
typedef struct { S2 x; S2 y; } S3;
typedef struct { S3 x; S3 y; } S4;
typedef struct { S4 x; S4 y; } S5;
typedef struct { S5 x; S5 y; } S6;
typedef struct { S6 x; S6 y; } S7;
typedef struct { S7 x; S7 y; } S8;
typedef struct { S8 x; S8 y; } S9;
typedef struct { S9 x; S9 y; } S10;
typedef struct { S10 x; S10 y; } S11;
typedef struct { S11 x; S11 y; } S12;
typedef struct { S12 x; S12 y; } S13;
typedef struct { S13 x; S13 y; } S14;
typedef struct { S14 x; S14 y; } S15;
typedef struct { S15 x; S15 y; } S16;
typedef struct { S16 x; S16 y; } S17;
typedef struct { S17 x; S17 y; } S18;
typedef struct { S18 x; S18 y; } S19;
typedef struct { S19 x; S19 y; } S20;
typedef struct { S20 x; S20 y; } S21;
typedef struct { S21 x; S21 y; } S22;
typedef struct { S22 x; S22 y; } S23;
typedef struct { S23 x; S23 y; } S24;
typedef struct { S24 x; S24 y; } S25;
typedef struct { S25 x; S25 y; } S26;
typedef struct { S26 x; S26 y; } S27;
typedef struct { S27 x; S27 y; } S28;
typedef struct { S28 x; S28 y; } S29;
typedef struct { S29 x; S29 y; } S30;
/*typedef struct { S30 x; S30 y; } S31;*/
S30 s;

int main(void) {
    printf("%jx\n", (uintmax_t)sizeof(s));
    return 0;
}

, а затем в Убунбу 17.10:

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-linux-gnueabi-gcc -std=c99 main.c

работает. Но если мы раскомментируем S31, произойдет сбой:

main.c:35:16: error: type ‘struct <anonymous>’ is too large
typedef struct { S30 x; S30 y; } S31;

Таким образом, максимальный размер составляет от 2 ^ 30 до (2 ^ 31 - 1).

Тогда мы можем преобразовать S30 в:

typedef struct { S29 x; S29 y; uint8_t a[(2lu << 29) - 1]; } S30;

и с этим мы определяем, что максимальный размер в этой реализации равен 2^31 - 1 == PTRDIFF_MAX.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...