Подтвердить что ты не робот

Сколированы ли скобки при определении размера массива?

Следующая программа печатает тот же номер дважды на gcc 4.8.2:

#include <stdio.h>

int main()
{
    char a[13];
    printf("sizeof a  is %zu\n", sizeof a );
    printf("sizeof(a) is %zu\n", sizeof(a));
}

В соответствии с этот пост reddit gcc не является стандартно-совместимым в этом отношении, потому что выражение в скобках не входит в список исключений, когда array-to- распад указателя не происходит.

Этот парень прав? Вот соответствующая стандартная цитата:

За исключением случаев, когда это операнд оператора sizeof или унарный оператор &, или литерал строковой буквы, используемый для инициализации массива типа символа, или это широкий строковый литерал, используемый для инициализации массива с помощью тип элемента, совместимый с wchar_t, значение l, которое имеет тип "массив типа", преобразуется в выражение, которое имеет тип "указатель на тип", который указывает на начальный элемент объекта массива и не является значением l. >

Чтобы быть ясным, он утверждает, что (a) должен приводить к распаду матрицы к указателю, потому что скобки не покрываются в списке выше (оператор sizeof, унарный &, строковый литерал как инициализатор).

4b9b3361

Ответ 1

Являются ли, казалось бы, лишние круглые скобки влияющими на семантику программы, является давняя проблема в стандарте C, которая до сих пор не была решена должным образом.

Обычно утверждается, что ((void*)0) технически не является константой нулевого указателя, потому что нет правила, которое говорит, что константа нулевого указателя в скобках является константой нулевого указателя.

Некоторые компиляторы выдают ошибку для char s[] = ("abc");, потому что, когда массив символов может быть инициализирован из строкового литерала, это правило не распространяется на строковые литералы в скобках.

Существует много подобных примеров. Вы нашли один из них.

Из того, что я могу сказать, консенсус в основном состоит в том, что правило должно быть тем, что делает С++, но что C никогда официально не принималось. С++ делает выражение в скобках функционально эквивалентным выражению, не заключенному в скобки, с несколькими явно выраженными исключениями. Это будет охватывать все эти вопросы сразу.

Так технически, парня можно считать правильным, но это чрезмерно строгая интерпретация стандарта, за которым никто не следует, поскольку общеизвестно, что стандарт здесь просто неисправен.

Ответ 2

Из C99, 6.5.1, в скобках:

Его тип и значение идентичны типу неравномерного выражения.

На первый взгляд, похоже, что это противоречит списку исключений, к которому вы обращаетесь (6.3.2.1):

За исключением случаев, когда это операнд оператора sizeof или унарный оператор & или строковый литерал, используемый для инициализации массива, выражение, которое имеет тип "массив типа", преобразуется в выражение с type "указатель на тип"...

Однако этот список находится в контексте операторов/операндов; круглые скобки не считаются оператором (на основе категоризации, подразумеваемой структурой раздела 6.5).