typedef unsigned int u32;
u32 bits[8]={1,2,4,8,16,32,64,128};
u32 i=0;
int wmain(int argc, wchar_t **argv)
{
i=0;while(i<8){printf("bits[%u]=%u \n", i, bits[i++]);}printf("\n");
i=0;while(i<8){printf("bits[%u]=%u \n", i++, bits);}printf("\n");
return 0;
}
постинкремент, странности.
Код:
Результат работы:
Цитата:
bits[1]=1
bits[2]=2
bits[3]=4
bits[4]=8
bits[5]=16
bits[6]=32
bits[7]=64
bits[8]=128
bits[0]=2
bits[1]=4
bits[2]=8
bits[3]=16
bits[4]=32
bits[5]=64
bits[6]=128
bits[7]=0
Можно как то объяснить такое странное поведение?
Разумеется можно. Всё можно объяснить. Данное поведение объясняется побочным эффектом. На компиляторе GCC всё будет иначе, на компиляторе Microsoft Visual C++ также, как в Ваших примерах.
Код:
i=0;while(i<8){printf("i=%u i++=%u i=%u\n", i, i++,i);}printf("\n");
Лично от себя - нерекомендую использовать и (пост/пре)инкремент и саму переменную как 2 разных параметра одной ф-ии, т.к. неизвестно в какой последовательности параметры ф-ии будут обрабатываться в скомпиленом файле, как сказал Iron_Phoenix в gcc результат будет другой конкретно у меня так:
Код:
bits[1]=1
bits[2]=2
bits[3]=4
bits[4]=8
bits[5]=16
bits[6]=32
bits[7]=64
bits[8]=128
bits[0]=1
bits[1]=2
bits[2]=4
bits[3]=8
bits[4]=16
bits[5]=32
bits[6]=64
bits[7]=128
bits[2]=2
bits[3]=4
bits[4]=8
bits[5]=16
bits[6]=32
bits[7]=64
bits[8]=128
bits[0]=1
bits[1]=2
bits[2]=4
bits[3]=8
bits[4]=16
bits[5]=32
bits[6]=64
bits[7]=128
вот это:
Цитата: arrjj
Лично от себя - нерекомендую использовать и (пост/пре)инкремент и саму переменную как 2 разных параметра одной ф-ии,
Просто переменную, как 2 разных параметра можно. Такой код будет нормально работать.
Код:
i=0;while(i<8){printf("bits[%u]=%u \n",i,bits);i++;}printf("\n");
Но вот с автоинкрементом в аргументе функции неожиданно UB вылезло.
Цитата: kisssko
Просто переменную, как 2 разных параметра можно. Такой код будет нормально работать.
Но вот с автоинкрементом в аргументе функции неожиданно UB вылезло.
Код:
i=0;while(i<8){printf("bits[%u]=%u \n",i,bits);i++;}printf("\n");
Но вот с автоинкрементом в аргументе функции неожиданно UB вылезло.
невнимательно читаешь:
[quote=arrjj]
и (пост/пре)инкремент и саму переменную
[/quote]
Вычисление параметров функций справа налево.
Цитата: cheburator
Вычисление параметров функций справа налево.
Угу, это ты авторам C++ компиляторов расскажи, они будут сильно удивлены ;)
например:
Код:
#include <stdio.h>
using namespace std;
unsigned int i=0;
int main()
{
i=0;while(i<8){printf("%u %u %u \n", i, i++,i);}printf("\n");
return 0;
}
using namespace std;
unsigned int i=0;
int main()
{
i=0;while(i<8){printf("%u %u %u \n", i, i++,i);}printf("\n");
return 0;
}
Компиленый в g++:
Код:
1 0 0
2 1 1
3 2 2
4 3 3
5 4 4
6 5 5
7 6 6
8 7 7
2 1 1
3 2 2
4 3 3
5 4 4
6 5 5
7 6 6
8 7 7
Тоже но в VS2008C++:
Код:
1 0 1
2 1 2
3 2 3
4 3 4
5 4 5
6 5 6
7 6 7
8 7 8
2 1 2
3 2 3
4 3 4
5 4 5
6 5 6
7 6 7
8 7 8
А такой код (переменная не в глобале):
Код:
#include <stdio.h>
using namespace std;
int main()
{
unsigned int i=0;
i=0;while(i<8){printf("%u %u %u \n", i, i++,i);}printf("\n");
return 0;
}
using namespace std;
int main()
{
unsigned int i=0;
i=0;while(i<8){printf("%u %u %u \n", i, i++,i);}printf("\n");
return 0;
}
в g++:
Код:
1 0 1
2 1 2
3 2 3
4 3 4
5 4 5
6 5 6
7 6 7
8 7 8
2 1 2
3 2 3
4 3 4
5 4 5
6 5 6
7 6 7
8 7 8
MSVC++2008:
Код:
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
(В 2010-й студии тожесамое) интересно увидеть как этот пример mingw будет компилить и borland'овский компилер:D
Цитата: arrjj
Угу, это ты авторам C++ компиляторов расскажи, они будут сильно удивлены ;)
Ну в нашем конкретном случае справа налево.
А вообще, насколько я знаю, разрабы компиляторов имеют полное право на это, в полном соответствии со стандартом ISO C++
Если вы на это закладываетесь, то у вас имеет место быть UB(Undefined Behavior - что кстати мы и наблюдаем).
Чтобы избежать этого, вычислите все параметры ДО вызова функции.