Зачем вызывать оператор sizeof с двумя аргументами? - PullRequest
12 голосов
/ 08 июня 2009

Недавно я наткнулся на код, похожий на:

if(sizeof(var,2) == 4) { ... }

(где var - это тип)

Я был довольно удивлен, увидев два аргумента оператора sizeof. Быстрое сканирование стандарта ISO / ANSI C99 не дало никаких секретов. Я не мог придумать никакого чтения грамматики, которая позволила бы запятую там.

В поиске кода Google мне удалось найти пример этого синтаксиса в некотором коде PPC.

Это какой-то PPC-специфический синтаксис? Что это значит?

РЕДАКТИРОВАТЬ: Оказывается, что то, что я смотрел - а также связанный код - это синтаксис, специфичный для компилятор WindRiver Diab :

sizeof (тип, int-const):

Если int-const равно 0 sizeof , возвращает размер в байтах типа.

Если int-const равно 1 sizeof , возвращает выравнивание типа.

Если int-const равно 2 sizeof , возвращает целочисленную константу, обозначающую тип типа. Посмотрите "оператор sizeof" в Руководство пользователя Diab C / C ++ для значений.

Ух, они действительно перегрузили значение оператора sizeof.

EDIT2: Полная документация здесь: http://www.vxdev.com/docs/vx55man/diab5.0ppc/c-additi.htm#3001432

Ответы [ 5 ]

9 голосов
/ 08 июня 2009

В ходе дальнейших исследований я обнаружил, что это поведение специфично для компилятора WindRiver Diab . Пожалуйста, см. РЕДАКТИРОВАТЬ в вопросе для деталей.

3 голосов
/ 08 июня 2009

Это выглядит как простое приложение оператора с запятыми , которое оценивает свой первый аргумент, отбрасывает результат, а затем оценивает свой второй аргумент.

В этом случае определяется, имеет ли литерал 2 размер 4. Часть "var" не имеет значения.

1 голос
/ 08 июня 2009

Похоже на красную сельдь. Я предполагаю, что вы случайно используете оператор запятой, а sizeof применяется к последнему значению.

0 голосов
/ 17 июня 2011

Важное замечание: ниже приведен псевдокод. аргументы для sizeof фактически никогда не оцениваются , что означает «выполнено», это всегда конструкция времени компиляции (и, следовательно, один из инструментов, предпочитаемых авторами шаблонов, например, перечисления).

обратите внимание, что я позаимствовал auto ниже у C ++ (0x); он говорит компилятору выводить тип из выражения инициализатора и упрощает примеры

Что многие не знают, так это то, что вы можете вызывать sizeof действительно так:

auto s = sizeof int;

Т.е., скобки не нужны. Следовательно, если вы передадите (x, y) sizeof, это эквивалентно

auto c = (x,y);
auto s = sizeof c;

или просто

auto c = x,y;
auto s = sizeof c;

x,y - это последовательность, где каждая часть оценивается слева направо, и последовательность получает значение последней части, в данном случае это y. Итак, исходный код примерно эквивалентен

auto s = sizeof y;

Так что мне кажется, что рассматриваемый компилятор действительно делает что-то действительно мозговое, так как он вводит расширение, которое также компилируется в других компиляторах, но с совершенно другим значением. Это плохо.

0 голосов
/ 08 июня 2009

Как уже упоминалось, оператор запятой применяется, а sizeof возвращает размер целочисленного литерала. Неожиданно это выглядит как ошибка автора, но может произойти какое-то зловещее кодирование.

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

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

...