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

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

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

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

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

Непонятное поведение - C++
Всем привет! В книге &quot;Прата - Язык программирования C++. Лекции и управжения 2011&quot; нашёл вот такой пример: const free_throws &amp;clone(...

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

Непонятное поведение функтора - C++
Почему-то не считается произведение 1 и 6 ... #include &lt;iostream&gt; #include &lt;algorithm&gt; #include &lt;functional&gt; #include &lt;vector&gt; ...

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

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

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

9
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
06.11.2010, 02:49 #2
Somebody, ну да, в оператор умножения объекты передаются по ссылке, а умножение происходит последовательно, поэтому сначала умножается a[0] на a[0]. После этого a[0] == 4. А затем a[1] == 1 умножается на новое a[0], которое уже равно четырём.
Если ты умножишь массив на константу, то всё посчитается так, как и должно быть интуитивно.

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

Возможно, в реализации там сначала умножается исходный массив, а потом меняется местами с новым.
В любом случае, константность ссылки это не отменяет, поэтому, действительно, очень странно.
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,494
07.11.2010, 00:50 #7
Somebody, скажите пожалуйста, а что Вы делаете этой строкой?


Цитата Сообщение от Somebody Посмотреть сообщение
valarray <int>a(2);
Я тут порылся, но
аналогов не нашёл
0
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 08:49 #8
kravam, см. второй конструктор по твоей же ссылке.
0
Somebody
2791 / 1602 / 147
Регистрация: 03.12.2007
Сообщений: 4,198
Завершенные тесты: 1
10.01.2013, 17:36  [ТС] #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" я так в стандарте не нашёл.
0
diagon
Higher
1930 / 1196 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.01.2013, 20:14 #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.
1
10.01.2013, 20:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.01.2013, 20:14
Привет! Вот еще темы с ответами:

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

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