Sizeof ("" + 0)!= sizeof (char *) Ошибка или undefined поведение?
Следующая программа C:
#include <stdio.h>
int main(void)
{
printf("%u %u %u\n",sizeof "",sizeof(""+0),sizeof(char *));
return 0;
}
выводит 1 4 4 при компиляции с GCC в Linux, но выводит 1 1 4 при компиляции с Microsoft Visual С++ в Windows. Результат GCC - это то, чего я ожидал бы. Различаются ли они потому, что MSVC имеет ошибку или потому, что sizeof ("" + 0) undefined? Для обоих компиляторов поведение (то есть, будет ли среднее значение напечатано равным первому значению или последнему значению) одинаково независимо от строкового литерала или целочисленной константы, которую вы используете.
Соответствующей ссылкой в стандарте ANSI C, как представляется, является 6.2.2.1 - Lvalues и обозначения функций:
"За исключением случаев, когда он является операндом оператора sizeof... значение lvalue, которое имеет тип" массив типа ", преобразуется в выражение, которое имеет тип" указатель на тип ", который указывает на начальный элемент объекта массива и не является lvalue".
Здесь, хотя "Исключить" не следует применять, потому что в sizeof ("+ 0) литерал array/string является операндом + not sizeof.
Ответы
Ответ 1
Поскольку "fooabc"
имеет тип char[7]
, sizeof("fooabc")
дает то же самое, что и sizeof(char[7])
. Однако массивы могут быть неявно преобразованы - часть, которую вы указали, - указателям (некоторые ошибочно называют этот "распад" ), и поскольку это необходимо для работы арифметики (+
), ""+0
будет иметь тип char*
. А указатель char может иметь разный размер, чем массив. В этом отношении поведение MSVC кажется нарушенным.
Ответ 2
Я предполагаю, что это ошибка MSVC.
""+0
берет адрес ""
(который затухает в типе char*
) и суммирует 0 с ним. Этот тип выражения char*
.
Поиграйте немного с этим: какое значение ""+0
? и ""+1
? и sizeof(""+1)
?
Ответ 3
Похож на ошибку в MSVC. По-видимому, оптимизатор удаляет +0
, прежде чем делать правильный анализ типов.