Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222

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

05.11.2010, 16:51. Показов 2100. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.11.2010, 16:51
Ответы с готовыми решениями:

Странное поведение std::string, полученного из std::stringstream
Есть код #include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;cstring&gt; int main() { std::stringstream stream; ...

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

Непонятное поведение программы
Доброго времени суток. Уважаемые форумчане, очень нуждаюсь в вашей консультации насчёт своей программы. Я не стану освещать задачу, которую...

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

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

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


Цитата Сообщение от Somebody Посмотреть сообщение
valarray <int>a(2);
Я тут порылся, но
аналогов не нашёл
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 08:49
kravam, см. второй конструктор по твоей же ссылке.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
10.01.2013, 17:36  [ТС]
Всплыла тут эта тема... В стандарте есть такая фраза: "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
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.01.2013, 20:14
В стандарте (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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.01.2013, 20:14
Помогаю со студенческими работами здесь

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

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

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

Непонятное поведение функции
Есть некоторый метод класса: int mustAttack(Chess &amp;chess, Player&amp; p1, Player&amp; p2, int atackerName, int chessid) { if (chess.alive)...

Непонятное поведение rvalue/lvalue
Всем привет, объясните, пожалуйста, немного про р-вэлью и л-вэлью в этом коде: #include &lt;iostream&gt; using namespace std; void...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru