Функция, передающая аргументы в обратном порядке - PullRequest
7 голосов
/ 02 октября 2010

Вот моя функция:

void abc(char  *def, unsigned int w, unsigned int x, unsigned int y, unsigned int z)
{
   printf("val 1 : %d\n", w);
   printf("val 2 : %d\n", x);
   printf("val 3 : %d\n", y);
   printf("val 4 : %d\n", z);
}

и вот где я вызываю эту функцию:

unsigned int exp[4] = { 1, 2, 3, 4 };
unsigned short count = 0;
abc(anyarray, exp[count++], exp[count++], exp[count++], exp[count++]);

и вот результат, который я ожидаю:

val1 : 1
val2 : 2
val3 : 3
val4 : 4

но то, что я получаю, полностью противоположно этому:

val1 : 4
val2 : 3
val3 : 2
val4 : 1

Не знаю почему? Любая помощь будет оценена.

Ответы [ 7 ]

8 голосов
/ 02 октября 2010

из стандартных документов, 5,4

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

Пример из самой Стандартной документации,

i = v[i ++]; / / the behavior is undefined

И по той же самой причине, что

abc(anyarray, exp[count++], exp[count++], exp[count++], exp[count++]); не определено ..

4 голосов
/ 02 октября 2010

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

Попробуйте:

abc(anyarray, exp[count], exp[count+1], exp[count+2], exp[count+3]);  
count += 4; 
2 голосов
/ 02 октября 2010

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

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

abc(anyarray, exp[count++], exp[count++], exp[count++], exp[count++]);

Порядок вычисления аргументов abc равен неопределен , но выражение вызывает неопределенное поведение , поскольку вы пытаетесь изменить переменную count более одного раза между двумя последовательностями точек.

Кроме того, использование неверного спецификатора формата в printf() также вызывает UB. Убедитесь, что вы использовали правильные спецификаторы формата (например, %u для unsigned int) в printf().

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

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

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

0 голосов
/ 10 января 2011

Вы получили это, потому что вы вызвали adb(exp,a,b,c,d) в соответствии с вашей проблемой, но во время вызова функции d сначала помещается в стек, а затем c ,b соответственно. Когда вы передали exp[count++] в последнем аргументе, который будет сначала обрабатывать стек, значит 1 сначала нажимается, затем 2, затем 3, затем 4. И в вызванной функции pop выполняется, и вы получаете w=4 x=3 y=2 z=1, вот и все.

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

Это из-за соглашения о вызовах. В _cdecl, соглашении о вызовах по умолчанию для программ на c / c ++ (согласно Microsoft), параметры передаются в стеке функции в обратном порядке. Из-за этого параметры также оцениваются в обратном порядке.

...