2013-02-22 2 views
2

У меня есть небольшой код, но я не мог понять, почему результат такой.
Здесьc функция оценки параметров и прохождения

#include <stdio.h> 

int f(int i, int j, int k); 

int main(int argc, char const *argv[]) 
{ 
    int a; 
    printf("enter a\n"); 
    scanf("%d",&a); 
    f(a,a++,a++); 
    printf("%d \n",a); 
    return 0; 
} 

int f(int i, int j, int k) 
{ 
    printf("function arguments \n"); 
    printf("%d %d %d\n",i,j,k); 
} 

вход: 4
выход: 6 5 4

+0

Теперь отступьте, пожалуйста, – ogzd

+1

Возможный дубликат [Порядок оценки параметров перед вызовом функции C] (http://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in -c) – unwind

+0

Скомпилируйте свой код с помощью 'gcc -Wall myprog.c -o myprog' и * gcc *, сообщите вам * предупреждение: операция в 'a' может быть не определена * –

ответ

4

Принятый ответ в отмеченном дубликата неверен.


f(a,a++,a++); 

Причины Неопределенное поведение. Он пытается изменить аргумент a без промежуточной точки последовательности. Кроме того, важно отметить, что порядок оценки аргументов функции равен Unspecified. Это может быть:

  • Слева направо или
  • справа налево или
  • Любой магический порядок компилятор выбирает.

Если вы используете GCC вы можете использовать предупреждающий флаг -wsequence-point, чтобы предупредить вас о точке последовательности связанного неопределенного поведения.


В GCC Если вы скомпилировать программу на строжайших уровней предупреждения, компилятор выдаст вам этот диагностический:

prog.c:10:18: error: operation on ‘a’ may be undefined [-Werror=sequence-point]
prog.c:10:18: error: operation on ‘a’ may be undefined [-Werror=sequence-point]


Ссылка:

C99 Стандартный §6.5 .2.2:
Para 10:

The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

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

+0

@pce: Это неопределенное поведение ** и ** не Unspecified behavior **. Доказательство приведено в цитируемой вами цитате * C99 §6.5.2.2p10 *, он указывает, что есть точка последовательности непосредственно перед вызовом функции, она не говорит, что существует точка последовательности между оценкой аргументов подвыражения. –

+0

@pce Что вы думаете о C11 §6.5p2? – Sebivor

+0

@modifiablelvalue hehe, C11 является удивительным.^ – pce

1

f(a,a++,a++); кажется, неопределенное поведение, потому что:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

При использовании неопределенного поведения, не существует каких-либо требований от стандарта C.

+0

Thanx to all.I также видел много источников, которые мы не можем сообщить указанной последовательности, но есть миф о том, что оценка параметров слева направо, а передача - справа налево. Это правда? –

Смежные вопросы