sizeof ("" + 0)! = sizeof (char *) Ошибка или неопределенное поведение? - PullRequest
15 голосов
/ 01 февраля 2011

Следующая программа на 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 C ++ в Windows.Результат GCC - то, чего я ожидал.Они отличаются, потому что MSVC имеет ошибку или потому что sizeof ("" + 0) не определен?Поведение обоих компиляторов (т. Е. Равняется ли напечатанное среднее значение первому или последнему значению) одинаково независимо от используемого строкового литерала или целочисленной константы.

Соответствующая ссылка в ANSI CСтандартным представляется 6.2.2.1 - L-значения и обозначения функций:

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

Здесь, хотя" Except "не должен применяться, потому что в sizeof (" "+ 0) массив /Строковый литерал является операндом +, а не sizeof.

Ответы [ 3 ]

7 голосов
/ 01 февраля 2011

Поскольку "fooabc" имеет тип char[7], sizeof("fooabc") дает то же самое, что и sizeof(char[7]).Однако массивы могут быть неявно преобразованы - указанная вами часть - в указатели (некоторые люди ошибочно называют это «затуханием»), и поскольку это необходимо для работы арифметики (+), ""+0 будет иметь типchar*.И указатель на символ может иметь размер, отличный от массива.В связи с этим поведение MSVC кажется нарушенным.

1 голос
/ 01 февраля 2011

Похоже, ошибка в MSVC. Видимо, оптимизатор удаляет +0 перед выполнением правильного анализа типов.

1 голос
/ 01 февраля 2011

Полагаю, это ошибка MSVC.

""+0 принимает адрес "" (который затухает в типе char*) и суммирует 0 с ним. Этот тип выражения char*.

Поиграйте немного с этим: каково значение ""+0? а из ""+1? и из sizeof(""+1)?

...