Это неопределенное поведение в C/C++

int foo(int c){
    return c;
}

int main(void){
    int a=5,c;
    c = foo(--a) + a; 
}

Будет ли это вызывать неопределенное поведение в C/C++? думаю нет не будет.

Прочитав все ответы, я не могу понять, является ли это неопределенным поведением или неопределенным поведением.


person jaya    schedule 22.03.2011    source источник
comment
Нет, не будет, потому что не скомпилируется. (Где точка с запятой!)   -  person flight    schedule 22.03.2011
comment
stackoverflow.com/questions/4176328/ имеет много информации об этом.   -  person Steve Jessop    schedule 22.03.2011
comment
Если вы не реализуете компилятор или набор тестов для компилятора, или если в вашей компании не работает группа языковых юристов, я бы поставил под сомнение необходимость даже знать это. Да, здесь, в SO, есть несколько человек, которые могут ответить на этот вопрос (и вы найдете больше на comp.lang.c++.moderated и comp.std.c++ в Usenet), но их не так много, и даже они иногда расходятся во мнениях по тонким вопросам. Что еще более важно, (некоторые) компиляторы также могут с ними не согласиться. Если код недостаточно ясен, чтобы, взглянув на него, достаточно опытный программист мог сказать Да! или Нет!, упростите его и готово.   -  person sbi    schedule 22.03.2011
comment
Я ответил неправильно, чтобы доказать свою точку зрения :)   -  person Matt Joiner    schedule 22.03.2011
comment
@Matt: твой ответ меня удивил! Заставил меня прыгнуть в свою копию FCD, чтобы проверить, не пропустил ли я что-то! @Erik прикрывает нас, хотя :)   -  person Matthieu M.    schedule 22.03.2011


Ответы (5)


Да, это неопределенное поведение - a и foo(--a) можно оценивать в любом порядке.

Для получения дополнительной справки см., например, Точка последовательности. После полного выражения и после оценки аргумента до foo есть точка последовательности, но порядок оценки подвыражений не указан на 5/4:

Если не указано иное, порядок вычисления операндов отдельных операторов и подвыражений отдельных выражений, а также порядок, в котором имеют место побочные эффекты, не определены. Между предыдущей и следующей точкой последовательности сохраненное значение скалярного объекта должно быть изменено не более одного раза путем вычисления выражения. Кроме того, доступ к предыдущему значению должен осуществляться только для определения сохраняемого значения. Требования настоящего параграфа должны выполняться для каждого допустимого порядка подвыражений полного выражения; в противном случае поведение не определено.

РЕДАКТИРОВАТЬ: Как указывает Прасун, поведение не определено из-за порядка оценки... не указано и становится неопределенным из-за доступ к предыдущему значению должен осуществляться только для определения сохраняемого значения

person Erik    schedule 22.03.2011
comment
Насколько я понимаю, это еще хуже. Ничто не помешает вычислить a после --a, но до foo(...), что может иметь значение, если foo еще больше изменит значение a. - person Matthieu M.; 22.03.2011
comment
@ Эрик: Это не единственная причина. Например, int c = foo(k--) + foo(--j) не вызывает поведения undefiend, хотя порядок оценки + не указан. - person Prasoon Saurav; 22.03.2011
comment
@Eric: поведение не только не указано, но и не определено. Прочитай мой ответ. :) - person Prasoon Saurav; 22.03.2011

Вы должны прочитать это, это скажет вам, что ваш код не определен, потому что + не является точкой следования и поэтому не определено, оценивается ли сначала f(--a) или a.

person filmor    schedule 22.03.2011
comment
Или прочтите отличный часто задаваемые вопросы по делу. - person sbi; 22.03.2011

Несмотря на то, что операнды оператора + могут быть оценены в любом порядке, поведение не определено, поскольку нарушает второе правило.

1) Между предыдущей и следующей точкой последовательности сохраненное значение объекта должно быть изменено не более одного раза путем вычисления выражения.

2) Кроме того, доступ к предыдущему значению должен осуществляться только для определения сохраняемого значения.

Следующее хорошо определено

c = foo(a-1) + a ;

Прочтите эту запись часто задаваемых вопросов, чтобы лучше понять неопределенное поведение и точки последовательности.

person Prasoon Saurav    schedule 22.03.2011

Согласно Википедии + не является точкой следования, поэтому порядок оценка не фиксирована, поэтому у вас неопределенное поведение.

person Björn Pollex    schedule 22.03.2011
comment
Используйте слово оценка вместо выполнение. - person Prasoon Saurav; 22.03.2011

Вы получите предупреждение о возвращаемом типе в основной функции, иначе все в порядке и c = 8 в конце main().

person Hiren    schedule 22.03.2011
comment
... нет, и не обязательно. - person flight; 22.03.2011
comment
да согласен не обязательно. Я имел в виду, что вы можете получить - person Hiren; 22.03.2011
comment
-1 - это неверно - почитайте точки последовательности: en.wikipedia.org/wiki/Sequence_point< /а> - person Paul R; 22.03.2011