0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47

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

21.10.2022, 12:13. Показов 4500. Ответов 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,312
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,312
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,312
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,544
Записей в блоге: 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,544
Записей в блоге: 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,312
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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru