Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.53/19: Рейтинг темы: голосов - 19, средняя оценка - 4.53
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47

Почему этот код не выполнится должным образом?

21.10.2022, 12:13. Показов 4464. Ответов 51

Студворк — интернет-сервис помощи студентам
На одном форуме наткнулся на то, что одному парню на собеседовании задали написать функцию нахождения минимума, он написал следующим образом:

C++
1
2
3
4
5
template <class T> 
T& min (T& a, T& b) 
{
  return (a<b)?a:b;
}
собеседующий ответил, что такой код не отработает должным образом на вызове:
min(a, b+1)

у меня вопрос, почему не работает? я запустил и он работает. (параметры стоило бы сделать константными, да, но почему код не отработает должным образом?)
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.10.2022, 12:13
Ответы с готовыми решениями:

Почему не работает должным образом?
vremyagoda = input (&quot;Введите какое сейчас время года? Зима?, Осень? Лето?, а может быть Весна?: &quot;) vremyasutok = input (&quot;Что у...

Не понимаю почему программа не работает должным образом
все работает исправно кроме условного оператора if,когда переменные меняются местами ничего не происходить код: a = float(input()) ...

Почему текст в колонках DataTables не форматируется должным образом?
При инициации таблицы задал классы колонок {className:&quot;Price&quot;,&quot;width&quot;: &quot;70px&quot; ,targets:, render:$.fn.dataTable.render.number( ' ',...

51
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.10.2022, 19:30
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от AlexVRud Посмотреть сообщение
min(T &a, T &b)
Цитата Сообщение от SergP01 Посмотреть сообщение
для меня ... &b - это адрес где эта переменна лежит
вырванная из контекста запись вида: &b может быть как операцией взятия адреса,
так и частью декларации ссылочного типа.

C++
1
2
3
int v;
int* p = &v; // <--- взятие адреса
int &ref = v ; // <--- объявление ссылки
обрати внимание: в обоих случах фигурирует &имя,
однако в зависимости от контекста,
амперсанд означает разные вещи.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
21.10.2022, 19:46
Цитата Сообщение от SergP01 Посмотреть сообщение
для меня ... &b - это адрес где эта переменна лежит
Что значит "для меня"?

В языке С++ & означает "адрес где эта переменна лежит" только в выражениях.

В объявлениях же & имеет совсем другой смысл.
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2022, 20:01
Ещё есть битовый оператор, там тож не про адрес
C++
1
2
3
    int a { 15 };
    int b { 7 };
    int c { a & b };
0
101 / 95 / 10
Регистрация: 31.08.2022
Сообщений: 1,014
21.10.2022, 21:36
Цитата Сообщение от Folian Посмотреть сообщение
Ещё есть битовый оператор, там тож не про адре
это всё фишки компиляторов...
у некоторых нет- 0b01001100
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
21.10.2022, 21:40
Цитата Сообщение от SergP01 Посмотреть сообщение
это всё фишки компиляторов...
??? Бинарный & - это некая "фишка компиляторов"?
0
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
23.10.2022, 13:55  [ТС]
да, суперский ответ, я знаю про временные объекты и для меня был странно, что код у меня нормально вызывается, но теперь ясно, что я подключил область видимости библиотеки stl и у меня банально вызывалась функция min из stl, так как она больше подходит(вернее только она и подходит), чем моя функция.
Спасибо больше

Добавлено через 9 минут
AlexVRud он еще ответил, что можно использовать smartpointerы вместо const, но не совсем понятно, что он имел в виду.
Вот их диалог(взял с сайта другого)

- Напишите функцию минимума.
- Ну да мы глобальным дефайном пользовались, что в движке нашем, там типа #define MIN(a, b) ((a<b)?a:b) только со скобочками как то хитро и вообще я синтаксис не помню.
- Напиши ручкой на листке функцию минимума, синтаксически правильную, которая компилировалась бы.
- Я задумался. И написал (http://www.cplusplus.com/refer... thm/min/):

template <class T> T& min (T& a, T& b) {
return (a<b)?a:b;
}
- Окей, тогда вот такой вариант вызова у вас не сработает должным образом:

min(a, b+1)
- Я задумался ещё крепче, ведь если создавать на сревнении лишнюю переменную временную, типа T& min (T a, T b), то при сравнении массивов мы вполне получим печаль. Думал минуты три.
- Давайте на этом завершим, вы не сможете ответить на дальнейшие вопросы если задумались над этим. Досвидания.

Это был первый вопрос что мне задали, и последний. Пока мы ехали в лифте, я спросил у собеседующего:
- А как правильно?
- Во первых, вы не написали const. А что касается передачи параметров - обычно ответом на этот вопрос вспоминают о смартпоинтерах..

а зачем смартпоинтеры ?
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
23.10.2022, 15:00
Цитата Сообщение от NewFive Посмотреть сообщение
я спросил у собеседующего
Шарашкина контора.
0
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
23.10.2022, 15:09  [ТС]

hoggy


поскольку в твоем случае функцию min, можно вызвать с временным объектом,
то возвращать результат по ссылке, это - плохая идея:
const int v = 10;
const int& r = min(v, v - 1);
в пример выше, время жизни временного объекта v-1 завершится сразу же,
как только завершится работа функции min
поэтому, ссылка const int& r будет ссылаться на мертвый объект.

таким образом, это - плохой дизайн, который провоцирует ошибки.
а у меня работает:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class T>
const T& min( const T& a, const T& b)
{
    std::cout << "MyMin" << std::endl;
    return (a < b) ? a : b;
}
 
int main()
{
        int a = 7;
    int b = 10;
 
    const int& dw = min(a+0, b + 2);
    std::cout << dw << std::endl; // выводится число 7
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.10.2022, 19:33
Цитата Сообщение от NewFive Посмотреть сообщение
а у меня работает:
так только в деццком садике говорят.

взрослые люди понимают:
нужно что бы на машинах пользователей работало.

https://rextester.com/QGXE24019

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
template <class T> const T& min(const T& a, const T& b)
{
    std::cout << "MyMin" << std::endl;
    return (a < b) ? a : b;
}
 
int main()
{
    int a = 7;
    int b = 10;
 
    const int& r = min(a + 1, b + 2);
    std::cout << r << '\n';
}
warnings:
Code
1
2
3
4
828362364/source.cpp: In function ‘int main()’:
828362364/source.cpp:15:23: warning: ‘<anonymous>’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     std::cout << r << '\n';
                       ^~~~
output:
Code
1
2
MyMin
0
как думаешь, число 0 - это тот результат,
на который рассчитывал пользователь?

причина такого поведния - UB,
вызванное использованием невалидной ссылки.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
23.10.2022, 22:24
Цитата Сообщение от NewFive Посмотреть сообщение
а у меня работает:
Вы фактически переписали стандартную функцию std::min, которая устроена точно так же. Но в вашем конкретном примере все "работает" лишь случайно.

Переданные вами временные объекты будут уничтожены и об этом нужно помнить при использовании таких функций. Но уничтожены они будут не сразу после возвращения из функции min, как вам неправильно написали выше, а только в конце полного выражения, содержащего вызов этой функции. Поэтому вы можете предавать полученную ссылку куда угодно дальше в рамках все того же полного выражения и ссылка будет оставаться работоспособной.

Например

C++
1
2
3
4
5
6
void foo(const int &v)
{
   std::cout << v << std::endl;
}
...
foo(min(a+0, b + 2));
или даже

C++
1
2
const int *p;
p = &min(a+0, b + 2), printf("Hello World\n"), foo(*p);
Это важное свойство С++, которым просто нужно уметь правильно пользоваться. Никакого "плохого дизайна" или "ошибок дизайна" в такой реализации функции min нет. Болтовня про "плохой дизайн" в данном случае - просто болтовня ради болтовни.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
24.10.2022, 04:17
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Никакого "плохого дизайна" или "ошибок дизайна" в такой реализации функции min нет. Болтовня про "плохой дизайн" в данном случае - просто болтовня ради болтовни.
но при этом:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
все "работает" лишь случайно.
болтун.
0
24.10.2022, 04:31

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
но при этом:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
все "работает" лишь случайно
Видите, народ, как он аккуратненько вырезал кусочек из моего исходного "Но в вашем конкретном примере все "работает" лишь случайно"?

Фактически, все бредни которые гонят в этот форум подобные болтуны и ламеры - вариации этой же демагогии. Просто не обращайте на них внимания.

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
24.10.2022, 04:50
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Видите, народ, как он аккуратненько вырезал кусочек
я назвал плохим дизайн, который провоцирует ошибки.
и о чудо! за примерами далеко ходить не пришлось.
0
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
24.10.2022, 14:04  [ТС]
TheCalligrapher
но в моем случае я же потом вызываю cout, после выражения, в котором min, и получаю нужный результат(хотя в gcc компиляторе выдает неправильный результат, но как я понял, по правилам там должна быть ошибка).

Но правильно ли я понимаю, что раз так, то всегда нужно результат выполнения min записывать по значению? если хочешь использовать его и дальше, а не только в выражении min.
то ест вот так: int dw = min(a1 + 1, b1);
а не const int &dw = min(a1 + 1, b1);

Добавлено через 8 минут
так только в деццком садике говорят.

взрослые люди понимают:
нужно что бы на машинах пользователей работало.
Да, я посмотрел и в gcc не работает, просто странно, что в stl так реализовали метод.
В любом случае мы передаем аргумент

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T> const T& min(const T& a, const T& b)
{
    std::cout << "MyMin" << std::endl;
    return (a < b) ? a : b;
}
 
int main()
{
    int a = 7;
    int b = 10;
 
    const int& r = min(a + 1, b + 2); мы по сути передаем временное выражение и привязываем его к параметрам функции, а как только мы выходим из функции, то ссылки удаляются, вместе со своим значением, которое они хранят, так? 
    std::cout << r << '\n';
}
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
24.10.2022, 14:39
Цитата Сообщение от NewFive Посмотреть сообщение
то всегда нужно результат выполнения min записывать по значению?
Capturing the result of std::min by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned
т.е. если засунуть два lvalue - можно и ссылку брать
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,538
Записей в блоге: 1
24.10.2022, 14:44
Цитата Сообщение от hoggy Посмотреть сообщение
нужно что бы на машинах пользователей работало.
ну, вообще-то для компилируемых языков нужно, чтобы в рабочий код компилировалось. А это уже делается на стороне разработчика.
Не вижу ничего ужасного в UB-коде "а у меня компилируется в рабочий код".
Мы ж его не отдаём в виде исходников всему миру.
Сделали сборку с конкретными нужными нам условиями, протестировали и можно быть уверенным в бинарнике.
Зачем давать гарантии того, что код одинаково скомпилируется и для тостера и для денди-плейстейшн. Если мы под них не делаем сборок?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
24.10.2022, 15:48
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Не вижу ничего ужасного в UB-коде "а у меня компилируется в рабочий код".
похоже, ты ошибся сайтом.
тебе сюда
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,538
Записей в блоге: 1
24.10.2022, 15:54
hoggy, какие же айтишники душнилы...

Добавлено через 1 минуту
твоя цитата
Цитата Сообщение от hoggy Посмотреть сообщение
нужно что бы на машинах пользователей работало.
можешь пояснить, что может не заработать на машинах пользователей? протестированный перед релизом бинарник?
0
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
24.10.2022, 17:22  [ТС]
т.е. если засунуть два lvalue - можно и ссылку брать
да, разобрался, спасибо, теперь во всем разобрался.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
24.10.2022, 18:36
Цитата Сообщение от Folian Посмотреть сообщение
т.е. если засунуть два lvalue - можно и ссылку брать
Ссылку можно брать всегда, если знаешь, что она будет оставаться корректной столько, сколько нужно. Но это - общее прописное правило.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.10.2022, 18:36

Код выводится в браузер, а не обрабатывается должным образом.
Здравствуйте!Проблема такая: при загрузке этого кода браузер выводит этот код, а должен график синуса Что может быть не так?? &lt;?php ...

Не получается должным образом получить HTML код сайта программным способом
Здравствуйте! Недавно решил сделать прогу на C#, а чтобы она нормально работала нужно считывать инф-цию с сайта. Информация считывается, но...

Как изменить код программы чтобы все условия выполнялись должным образом?
Здравствуйте! Вот код программы: #include &lt;iostream&gt; #include &lt;time.h&gt; #include &lt;math.h&gt; using namespace std; int t; ...

Почему невозможно открыть код таким образом и почему форма с ним никак не контактирует
И при двойном клике на элемент, открывается, а точнее переходит, на исходный код. Никак не пойму в чем проблема, а ответ по-любому...

Не работает должным образом LZ-78 (компрессор) c++
Приветствую, форумчане! Прошу помочь с небольшим проектом. Есть код на C++, но не могу реализовать работу с файлами. Только прошу, не...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru