Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

постинкремент, странности.

41K
10 мая 2011 года
kisssko
108 / / 28.10.2010
Код:
Код:
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



Можно как то объяснить такое странное поведение?

63K
10 мая 2011 года
Iron_Phoenix
5 / / 23.08.2010
Разумеется можно. Всё можно объяснить. Данное поведение объясняется побочным эффектом. На компиляторе GCC всё будет иначе, на компиляторе Microsoft Visual C++ также, как в Ваших примерах.
277
10 мая 2011 года
arrjj
1.7K / / 26.01.2011
Такой примерчик вам всё объяснит.
 
Код:
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
11
10 мая 2011 года
oxotnik333
2.9K / / 03.08.2007
вот это:
http://alenacpp.blogspot.com/2005/11/sequence-points.html
можно почитать для ясности
41K
10 мая 2011 года
kisssko
108 / / 28.10.2010
Цитата: arrjj

Лично от себя - нерекомендую использовать и (пост/пре)инкремент и саму переменную как 2 разных параметра одной ф-ии,


Просто переменную, как 2 разных параметра можно. Такой код будет нормально работать.

 
Код:
i=0;while(i<8){printf("bits[%u]=%u \n",i,bits);i++;}printf("\n");

Но вот с автоинкрементом в аргументе функции неожиданно UB вылезло.
277
10 мая 2011 года
arrjj
1.7K / / 26.01.2011
Цитата: kisssko
Просто переменную, как 2 разных параметра можно. Такой код будет нормально работать.
 
Код:
i=0;while(i<8){printf("bits[%u]=%u \n",i,bits);i++;}printf("\n");

Но вот с автоинкрементом в аргументе функции неожиданно UB вылезло.



невнимательно читаешь:
[quote=arrjj]
и (пост/пре)инкремент и саму переменную
[/quote]

350
20 мая 2011 года
cheburator
589 / / 01.06.2006
Вычисление параметров функций справа налево.
277
20 мая 2011 года
arrjj
1.7K / / 26.01.2011
Цитата: 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;
}

Компиленый в 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

Тоже но в 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

А такой код (переменная не в глобале):
 
Код:
#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;
}

в 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

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

(В 2010-й студии тожесамое) интересно увидеть как этот пример mingw будет компилить и borland'овский компилер:D
350
23 мая 2011 года
cheburator
589 / / 01.06.2006
Цитата: arrjj
Угу, это ты авторам C++ компиляторов расскажи, они будут сильно удивлены ;)


Ну в нашем конкретном случае справа налево.
А вообще, насколько я знаю, разрабы компиляторов имеют полное право на это, в полном соответствии со стандартом ISO C++

1
23 мая 2011 года
kot_
7.3K / / 20.01.2000
Порядок вычисления параметров вызова функции не определен.
Если вы на это закладываетесь, то у вас имеет место быть UB(Undefined Behavior - что кстати мы и наблюдаем).
Чтобы избежать этого, вычислите все параметры ДО вызова функции.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог