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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Somebody
2786 / 1600 / 145
Регистрация: 03.12.2007
Сообщений: 4,190
Завершенные тесты: 1
#1

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

05.11.2010, 16:51. Просмотров 1155. Ответов 9
Метки нет (Все метки)

Есть такой код:
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];
Что бы это всё могло значить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.11.2010, 16:51     Непонятное поведение std::valarray
Посмотрите здесь:

Непонятное поведение программы - C++
Пишу статическую либу. В ней есть кусок кода, который уходит в рекурсию.. Только причины мне непонятны.. Вот кусок кода std::string...

Непонятное поведение программы - C++
Привет народ, вот кароч: #include&quot;stdafx.h&quot; #include&quot;iostream&quot; using namespace std; class calc{ int *i, *j; public: int...

Непонятное поведение простой функции - C++
Решал одну задачу на рекурсию, долго не мог добится результата пока не понял что проблема не в рекурсии а в аргументах функции, сделал...

Непонятное поведение простейшей формулы - C++
Добрый вечер. Дано: double a; double d; unsigned int c; unsigned int b; for loop{ //манипуляции

Непонятное мне поведение функции - C++
Эта функция себя странно ведёт. Она работает и если с первого раза ввести цифры с клавиатуры, то работает корректно, но если сначала ввести...

Непонятное поведение list, vector в другом классе - C++
Салют. class _auxObserver { --- list&lt;gmObjBase*&gt; mObservedObj; vector&lt;int&gt; b; public: ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
volovzi
267 / 169 / 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
2786 / 1600 / 145
Регистрация: 03.12.2007
Сообщений: 4,190
Завершенные тесты: 1
06.11.2010, 12:24  [ТС]     Непонятное поведение std::valarray #3
Цитата Сообщение от volovzi Посмотреть сообщение
в оператор умножения объекты передаются по ссылке, а умножение происходит последовательно, поэтому сначала умножается a[0] на a[0]. После этого a[0] == 4.
Так operator* должен же возвращать временный объект, а потом уже из него копируется в a?
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.11.2010, 12:34     Непонятное поведение std::valarray #4
Верно. Но в процессе умножения массив (а именно элемент a[0]) модифицируется. Почему — я объяснил в предыдущем сообщении.
Somebody
2786 / 1600 / 145
Регистрация: 03.12.2007
Сообщений: 4,190
Завершенные тесты: 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
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.11.2010, 19:05     Непонятное поведение std::valarray #6
Да, действительно, ссылка константная. Мне сначала показалось, что нет.
В таком случае, наверное, глюк gcc.

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


Цитата Сообщение от Somebody Посмотреть сообщение
valarray <int>a(2);
Я тут порылся, но
аналогов не нашёл
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 08:49     Непонятное поведение std::valarray #8
kravam, см. второй конструктор по твоей же ссылке.
Somebody
2786 / 1600 / 145
Регистрация: 03.12.2007
Сообщений: 4,190
Завершенные тесты: 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
Еще ссылки по теме:

Шаблонный класс с шаблонным оператором внутри - непонятное поведение - C++
Написал &quot;кукольный&quot; пример, дабы не смущать читателей ненужными деталями. #include &lt;iostream&gt; template &lt;typename T&gt; struct foo...

Странное рекурсивное поведение объекта std::cout - C++
Пытался организовать очередь при помощи шаблона и наткнулся на &quot;странное&quot; поведение: // Организация очереди при помощи шаблона ...

Странное поведение операции XOR и std::cin - C++
Объясните, пожалуйста, почему этот код работает правильно: /* Обмен значений двух переменных без использования дополнительной переменной...

C++ std::thread разное поведение на linux и windows - C++
Столкнулся с странным поведением std::thread, при использовании метода detach. Пример кода: #include &lt;iostream&gt; #include &lt;thread&gt;...


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

Или воспользуйтесь поиском по форуму:
diagon
Higher
1928 / 1194 / 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
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru