Форум программистов, компьютерный форум CyberForum.ru

Непонятное поведение std::valarray - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Somebody
2769 / 1582 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
05.11.2010, 16:51     Непонятное поведение std::valarray #1
Есть такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <valarray>
 
using namespace std;
 
int main()
{
    valarray<int> a(2);
    a[0] = 2; a[1] = 1;
    a = a[0] * a;
    cout << a[0] << ' ' << a[1] << endl;
    cin.peek();
}
Если компилировать Borland'ом, выводит интуитивно понятное 4 2, а если g++, то 4 4. Если было бы
C++
1
a *= a[0];
то a[0] передаётся по ссылке, undefined behaviour. Но здесь же вроде должен создаваться временный valarray, из которого потом копируется в a. Sequence point'ы есть до и после вызова operator* и operator=. Но это всё равно выполняется как
C++
1
2
a[0] = a[0] * a[0];
a[1] = a[0] * a[1];
Что бы это всё могло значить?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.11.2010, 02:49     Непонятное поведение std::valarray #2
Somebody, ну да, в оператор умножения объекты передаются по ссылке, а умножение происходит последовательно, поэтому сначала умножается a[0] на a[0]. После этого a[0] == 4. А затем a[1] == 1 умножается на новое a[0], которое уже равно четырём.
Если ты умножишь массив на константу, то всё посчитается так, как и должно быть интуитивно.

Если же тебе неохото заводить новую переменную, то пиши так:
C++
1
a = a * int(a[0]);
Somebody
2769 / 1582 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
06.11.2010, 12:24  [ТС]     Непонятное поведение std::valarray #3
Цитата Сообщение от volovzi Посмотреть сообщение
в оператор умножения объекты передаются по ссылке, а умножение происходит последовательно, поэтому сначала умножается a[0] на a[0]. После этого a[0] == 4.
Так operator* должен же возвращать временный объект, а потом уже из него копируется в a?
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.11.2010, 12:34     Непонятное поведение std::valarray #4
Верно. Но в процессе умножения массив (а именно элемент a[0]) модифицируется. Почему — я объяснил в предыдущем сообщении.
Somebody
2769 / 1582 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
06.11.2010, 18:48  [ТС]     Непонятное поведение std::valarray #5
С какого он модифицируется, если он передаётся по константной ссылке?
Код
template <class T> valarray<T> operator* (const T& val, const valarray<T>& rhs);
Ладно, тогда что из следующего верно:
1) Правильный ответ 4 4. В Borland C++ 5.5.1 баг.
2) Правильного ответа нет, потому что undefined behaviour. Тогда по какому пункту стандарта оно?
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.11.2010, 19:05     Непонятное поведение std::valarray #6
Да, действительно, ссылка константная. Мне сначала показалось, что нет.
В таком случае, наверное, глюк gcc.

Возможно, в реализации там сначала умножается исходный массив, а потом меняется местами с новым.
В любом случае, константность ссылки это не отменяет, поэтому, действительно, очень странно.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
07.11.2010, 00:50     Непонятное поведение std::valarray #7
Somebody, скажите пожалуйста, а что Вы делаете этой строкой?


Цитата Сообщение от Somebody Посмотреть сообщение
valarray <int>a(2);
Я тут порылся, но
аналогов не нашёл
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 08:49     Непонятное поведение std::valarray #8
kravam, см. второй конструктор по твоей же ссылке.
Somebody
2769 / 1582 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
10.01.2013, 17:36  [ТС]     Непонятное поведение std::valarray #9
Всплыла тут эта тема... В стандарте есть такая фраза: "The valarray array classes are defined to be free of certain forms of aliasing, thus allowing operations on these classes to be optimized". В общем, идея valarray'ев такая:
http://en.cppreference.com/w/cpp/numeric/valarray
std::valarray and helper classes are defined to be free of certain forms of aliasing, thus allowing operations on these classes to be optimized similar to the effect of the keyword restrict in the C programming language. In addition, functions and operators that take valarray arguments are allowed to return proxy objects to make it possible for the compiler to optimize an expression such as v1 = a*v2 + v3; as a single loop that executes v1[i] = a*v2[i] + v3[i]; avoiding any temporaries or multiple passes...
Так что, думаю, g++ сделал всё нормально. Но точного определения этих "certain forms of aliasing" я так в стандарте не нашёл.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.01.2013, 20:14     Непонятное поведение std::valarray
Еще ссылки по теме:

Странное поведение операции XOR и std::cin C++
C++ Непонятное поведение программы
C++ Шаблонный класс с шаблонным оператором внутри - непонятное поведение

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.01.2013, 20:14     Непонятное поведение std::valarray #10
В стандарте (955 страница) есть такой пункт.
If the value of an element in the left-hand side of a valarray assignment operator depends on the value
of another element in that left-hand side, the resulting behavior is undefined.
Как-то мутно написано, но вроде подходит под ваш случай.
Проблема именно в присваивании, ибо a[0] * a вычисляется вполне корректно, а вот если в левую часть присваивания поставить другой valarray, то будет 4 2.
Yandex
Объявления
10.01.2013, 20:14     Непонятное поведение std::valarray
Ответ Создать тему
Опции темы

Текущее время: 07:44. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru