Влияние размера массива int на эквивалентность типов - PullRequest
2 голосов
/ 14 апреля 2009

Я читаю об эквивалентности типов в моем классе языков программирования, и я столкнулся с ситуацией в C, в которой я не уверен.

Это описывает "Эквивалентность типа" C как:

C использует форму эквивалентности типов, которая находится между именем и структурной эквивалентностью и которую можно свободно описать как «эквивалентность имени для структур и объединений, структурная эквивалентность для всего остального».

Так что, если у меня есть два массива разного размера, но одного базового типа:

typedef int A1[10];  
typedef int A2[20];

Поскольку все, что мне нужно, это структурная эквивалентность, могут ли эти два считаться структурно эквивалентными? В Си размер индекса является частью типа массива или нет?

Ответы [ 3 ]

3 голосов
/ 14 апреля 2009

Нет, это не так.

Вы можете попробовать sizeof(A1) и sizeof(A2) и увидеть, что они разные.

2 голосов
/ 14 апреля 2009

Нет, они не одного типа.

В C вы не получите ошибку, но в C ++, если вы попытаетесь, вы получите ошибку, похожую на:

ошибка C2440: «инициализация»: невозможно преобразовать из «int () [1024]» в «int () [512] '

Вот пример кода

int x[1024];
int y[512];
/*Create a pointer int[1024] type*/
int (*px)[1024] = &x;
/*Create a pointer int[512] type*/
int (*py)[512] = &y;

int (*py2)[512] = &x; /*<---compiling error in C++ but allowed in C even know it's wrong*/

Даже если знать, что последняя строка разрешена в C, два типа считаются разными. Также массив не совпадает с указателем на массив, но, как вы можете видеть, объявления типов различаются.

0 голосов
/ 15 апреля 2009

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

Я не совсем уверен, что ваша книга подразумевает под "структурной эквивалентностью", но задаюсь вопросом, относится ли это к целочисленному продвижению по умолчанию (но, похоже, также включает массивы?). Но в любом случае целочисленное продвижение - это очень важный вопрос, и вы должны потратить время на понимание. Распечатка ниже должна быть выполнена в соответствии с этими правилами:

unsigned int i = 0;
if (i < -1) {
        printf("This line is printed!\n");
}

Стандарт C (ISO / IEC 9899: 1990) содержит раздел с заголовком «обычные арифметические преобразования», определяющий поведение. Стандарт не находится в свободном доступе (напротив, он продается довольно дорого, поскольку стандарты ISO устанавливаются по цене за страницу ...), но если вы будете искать этот термин, вы сможете найти некоторую полезную информацию или цитаты. Некоторые проекты стандартов находятся в свободном доступе, однако представляют угрозу для тех, у кого большое недоверие, поскольку вы точно не знаете, что было изменено в окончательном стандарте.

...