Возможный дубликат:
Неопределенные Точки Поведения и Последовательности
Я использую Microsoft Visual C ++. Посмотрите на следующий пример:
int n = 5;
char *str = new char[32];
strcpy(str, "hello world");
memcpy(&str[n], &str[n+1], 6+n--);
printf(str);
// output is "hell world"
Так что неожиданно мой компилятор создает код, который первый уменьшает значение n и затем выполняет memcpy. Следующий источник сделает то, что я ожидал:
int n = 5;
char *str = new char[32];
strcpy(str, "hello world");
memcpy(&str[n], &str[n+1], 6+n);
n--;
printf(str);
// output is "helloworld"
Сначала я попытался объяснить это себе. Последний параметр помещается в стек первым, поэтому он может быть оценен первым. Но я действительно верю, что пост-инкремент / декремент гарантируется после следующей точки с запятой.
Итак, я запустил следующий тест:
void foo(int first, int second) {
printf("first: %i / second: %i", first, second);
}
int n = 10;
foo(n, n--);
Будет выведено «первое: 10 / второе: 10».
Итак, мой вопрос: есть ли определенное поведение в этой ситуации? Может кто-нибудь указать мне документ, где это описано? Нашел ли я ошибку компилятора ~~ O.O ~~?
Пример просто предназначен для того, чтобы больше не иметь смысла, он просто демонстрирует мою проблему и работает сам по себе.
Есть два связанных вопроса в игре. Во-первых, порядок выполнения аргументов функции неопределенные. Что гарантировано, так это то, что все выполняются перед вводом тела функции. Во-вторых, это не определено поведение, потому что вы меняете и читаете n
без каких-либо точек последовательности между этими выражениями.
Других решений пока нет …