Преобразование lvalue в rvalue массива в ISO C - PullRequest
6 голосов
/ 17 октября 2010

C ++ ANSI ISO IEC 14882 2003 Приложение C.1 (стр. 668):

Изменение: результатом условного выражения, выражения присваивания или выражения запятой может быть lvalue
Обоснование: C ++ является объектно-ориентированным языком, который делает больший акцент на lvalues. Например, функции могут возвращать lvalues.
Влияние на исходную функцию: изменение семантики четко определенной функции. Некоторые выражения C, которые неявно полагаются на преобразования lvalue-rvalue, дадут разные результаты. Например,

char arr[100];
sizeof(0, arr)

дает 100 в C ++ и sizeof(char*) в C.
...

Я читал это только сегодня, и я вспомнил, что пару месяцев спустя мой друг предложил проблему, которая заключалась в написании функции, которая возвращала бы 0, если она была скомпилирована с C ++, и 1, если она была скомпилирована с C Я решил это, воспользовавшись тем, что в Си структура была во внешней области видимости. Итак, учитывая эту новую информацию, я решил, что это будет еще одно решение вышеуказанной проблемы, которое я пробовал в Microsoft Visual Studio 2008, но независимо от того, скомпилирован ли он в код C или C ++, sizeof(0, arr) всегда дает 4. Итак 2 вопросы:

1.Что такое ISO C? Это текущий стандарт C? Это единственный (я слышал, C быстро развивается) 2. Это ошибка в Microsoft C ++?

TIA

Редактировать: Извините, что перепутал результат и отредактировал его:

Ответы [ 3 ]

5 голосов
/ 17 октября 2010

ISO C - это стандарт C. Текущий C99, но C1x прямо за углом. Если под быстрым вы подразумеваете новый стандарт каждые десять лет или около того, то да, он быстро развивается: -)

Раздел 6.5.3.4/3 ISO C99 гласит:

При применении к операнду, имеющему тип char, unsigned char или char со знаком (или его квалифицированную версию), результат равен 1.

При применении к операнду с типом массива результатом является общее количество байтов в массиве.

1 голос
/ 17 октября 2010

Или просто Microsoft C - это не ISO C, а какой-то другой стандарт C (если таковой существует).

Microsoft Visual C все еще поддерживает C89 [только], тогда как другие компиляторы, такие как gcc / clang и т. Д., Также поддерживают C99 , что является текущим стандартом.

C99 [Раздел 6.5.17/2] говорит

Левый операнд оператора запятой оценивается как пустое выражение; после его оценки есть точка последовательности. Затем вычисляется правый операнд; результат имеет свой тип и значение. 95

Таким образом, результат sizeof (0,arr) будет sizeof(char*) [из-за неявного преобразования lvalue в rvalue / автоматического затухания в тип указателя], а не 100*sizeof(char)

sizeof(arr) дал бы 100*sizeof(char) из 6.5.3.4/3

95) Оператор запятой не дает lvalue.


решил, что это будет еще одно решение вышеуказанной проблемы, которое я пробовал на Microsoft Visual Studio 2008, но независимо от того, скомпилирован ли он в C или C ++, код sizeof (0, arr) всегда дает 4.

C ++ 03 [5.18/1] Оператор запятой

Тип и Значением результата являются тип и значение правого операнда; результатом является lvalue, если его правый операнд равен.

То есть sizeof(0, arr) = sizeof (arr) и что будет равно 100* sizeof(char), а не = sizeof(char*).

Таким образом, MSVC ++ дает неверный результат (в случае кода C ++).

0 голосов
/ 17 октября 2010

Для массивов sizeof возвращает общий размер. Будьте осторожны с массивами, переданными как указатели.

C99 стандарт:

При применении к операнду с массивом типа, результатом является общее количество байтов в массиве

...