Функция передачи аргументов в обратном порядке

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

void abc(char  *def, unsigned int w, unsigned int x, unsigned int y, unsigned int z)
{
   printf("val 1 : %dn", w);
   printf("val 2 : %dn", x);
   printf("val 3 : %dn", y);
   printf("val 4 : %dn", 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 ответов


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

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

пример из самого стандартного документа,

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

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

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


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

попробуй:

abc(anyarray, exp[count], exp[count+1], exp[count+2], exp[count+3]);  
count += 4; 

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


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

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


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

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

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


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


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