Есть ли конкретная документация по поведению i=i-- в gcc?

Еще раз, наши самые любимые "i=i--" -подобные проблемы. В C99 у нас есть:

6.5 Выражение № 2: Между предыдущей и следующей точкой последовательности сохраненное значение объекта должно быть изменено не более одного раза.

70) Этот абзац отображает !!undefined!! операторные выражения, такие как

i = ++i + 1;

Но для неопределенного поведения могут быть варианты от случайного вывода до «задокументированного выполнения программы» (c99 3.4.3)

Итак, вопрос:

Документирует ли gcc поведение для операторов i=i++, i=i-- и т. д.?

Фактический код

int main(){int i=2;i=i--;return i;}

person osgx    schedule 25.08.2010    source источник
comment
Нет, gcc не документирует, что он делает в этом случае. Разработчики Gcc ищут, среди прочего, скорость сгенерированного кода. Документирование того, что делает этот пример, будет противоречить этой цели. Радость программистов, которые пишут код, подобный этому примеру, не имеет никакого значения по сравнению с улучшением результатов тестов.   -  person Pascal Cuoq    schedule 25.08.2010


Ответы (4)


GCC не документирует это поведение. На странице параметров предупреждений упоминаются проблемы с контрольными точками в -Wsequence-point, но не подсказка о четко определенной семантике нарушений.

У GCC есть хороший список C Поведение, определяемое реализацией, но здесь я также не нашел ссылок на эту проблему.

person schot    schedule 25.08.2010
comment
Я не уверен, как сейчас, но в прошлом люди GCC, когда это было возможно, открыто выступали за стандарты. IOW, если стандарт говорит, что он не определен или не указан, значит, он находится в GCC. - person Dummy00001; 25.08.2010

Решение о том, что она делает, остается за внутренней реализацией. Вы можете использовать -S и проверить сгенерированный код, чтобы определить точную последовательность событий.

person Ignacio Vazquez-Abrams    schedule 25.08.2010
comment
Есть ли документ о таких случаях? - person osgx; 25.08.2010
comment
а что такое бэкэнд в GCC? Будет ли это отличаться, например, для x86 и sparc? - person osgx; 25.08.2010
comment
Неопределенное поведение означает, что все является честной игрой. Компилятор может выбрать генерацию разного кода в разные дни недели. - person jamesdlin; 25.08.2010
comment
@jamesdlin, да, компилятор может запустить игру Hanoi в Emacs 13-го числа месяца, но обычно этого не происходит. И для фиксированной версии компилятора и платформы результаты одинаковы даже для разных уровней -O - person osgx; 27.08.2010

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

person mtvec    schedule 25.08.2010
comment
Если это будет задокументировано, я могу рассчитывать, что GCC с некоторыми версиями будет делать то, что было задокументировано. Да, мой код будет ошибочным для любого другого компилятора, но не для GCC - person osgx; 25.08.2010
comment
@osgx: Может быть, вы могли бы, но я думаю, что это вызовет гораздо больше проблем, чем оно того стоит. Это, например, очень сбивает с толку людей, читающих ваш код. И вообще, зачем вам делать что-то вроде i = i--? Вы должны знать, что вы хотите, чтобы он делал, так почему бы просто не написать это на правильном C++? - person mtvec; 25.08.2010
comment
этот случай пришел к нам из нашего большого набора тестов, частично написанного нашими тестировщиками. У них «очень» разный уровень владения языком C. - person osgx; 25.08.2010
comment
@osgx: страшно. Я бы заставил их всегда компилироваться с -Wall, что в любом случае является хорошей идеей. Это, в частности, активирует -Wsequence-point, о котором упоминает schot. - person Jens Gustedt; 25.08.2010
comment
@osgx Теперь, когда я немного лучше понимаю контекст, я думаю, что могу упомянуть статический анализатор, над которым мы с другими работаем (см. мою биографию). Он находит много неопределенного или неуказанного поведения, если анализируемый код попадает в правильное подмножество C. И наоборот, есть ли место с дополнительной информацией о работе, в которой у вас возник этот вопрос? - person Pascal Cuoq; 25.08.2010
comment
@Pascal Cuoq, этот тестовый пакет является частным и находится под запретом на использование. gcc определяет i=i-- довольно хорошо, и я часто использую опции -W -Wall -Wextra -pedantic -ansi для gcc. Также.. кажется, что исходный тест имеет зависимость данных от результата этого i=i--, но, в то же время, будет успешным в обоих тривиальных пониманиях этой конструкции. - person osgx; 25.08.2010

с какой стати ты хочешь это сделать? Серьезно. Мне любопытно.

person Dave Dopson    schedule 25.08.2010
comment
Этот код находится в тестовом наборе компилятора. Этот набор тестов работает нормально для некоторых версий gcc. - person osgx; 25.08.2010
comment
Это неопределенное поведение, поэтому допустимо любое поведение. Если ваш тест компилятора возвращает недействителен для любого компилятора, то ваш тест не работает, потому что он всегда должен возвращать действителен, независимо от того, является ли результат 2, 3, 4 или конец Вселенной, какой мы ее знаем. Конечно, мы можем придираться к тому, всегда ли поведение undefined имеет действительные или всегда недействительные результаты. ;) - person Secure; 25.08.2010
comment
Кстати, проверяли ли вы, что результаты совпадают на разных уровнях оптимизации? - person Secure; 25.08.2010
comment
@Secure, настоящий тест проходит успешно в обоих случаях, когда i=i-- работает. Он будет делать разное количество итераций, но будет успешным. Это тест для компилятора, а не для соответствия стандарту. В протестированных версиях gcc результат был одинаковым для всех протестированных уровней -O. - person osgx; 27.08.2010