Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Применяется const в параметрах функции? 
:(
    Опции темы
kemiisto
Дата 10.9.2014, 19:21 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Lukkoye, ну, давайте попробуем разложить всё по полочкам. Итак, вот ключевая цитата из Вашего первого(?) сообщения в этой теме.
Цитата(Lukkoye @  8.9.2014,  10:44 Найти цитируемый пост)
Это важно не только для читабельности, и оптимизации (древним компиляторам помогало оптимизировать код), но так же является важным требованием для строгих гарантий.

За оптимизации в древних компиляторах ничего не скажу, но остальное - не верно. И вот почему.

Полочка №1

Объявление функции - часть интерфейса, а её определение - детали реализации. Клиенты обладают информацией только об интерфейсе, и ничего сверх того, что специфицирует и гарантирует интерфейс, им не известно и не должно быть известно.

Полочка №2

Крайне желательно чтобы интерфейс и реализация соответствовали друг другу. В случае функции это означает, что список формальных параметров в объявление функции и её определени должны совпадать. Вплоть до квалификаторов. Поэтому вариант, где в объявлении нет квалификатора const, а в определении есть, отметаем сразу.

Полочка №3

Теперь мы приходим к двум вариантам функции, показанным ниже, в которых в первой строчке стоит объявление функции, а во второй - её определение.

Код
int foo(const int x);
int foo(const int x) { ... };


Код
int foo(int x);
int foo(int x) { ... };


А теперь посмотрите на эти два варианта только с точки зрения клиентского кода, который эту функцию будет вызывать и котором доступен только её интерфейс.

Код
int foo(const int x);


Код
int foo(int x);


Даёт ли первый вариант какие-либо дополнительные гарантии? Нет, никаких. Фактический параметр в обоих вариантах передаётся по значению, а значит будет скопирован при передаче и изменений в ходе выполнения функции не притерпит. Единтсвенное, что помимо этого сообщает функция в первом варианте, так это то, что и формальный параметр в ходе её выполнения изменений тоже не притерпит. НО! Это деталь реализации, которая клиентскому коду вообще знать незачем. 

Цитата(Lukkoye @  9.9.2014,  23:42 Найти цитируемый пост)
Прототип замалчивает свои намерения: то ли он собирается перетирать аргумент. Толи писал г_о_в_н_о_кодер.

Ещё раз повторю, Вы ошибаетесь. Прототип своих намерений не замалчивает. Фактический аргумент передаётся по значению, и во время выполнения функции его значение не измениться.

Это сообщение отредактировал(а) kemiisto - 10.9.2014, 19:21


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Lukkoye
Дата 10.9.2014, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(kemiisto @  10.9.2014,  19:21 Найти цитируемый пост)
Объявление функции - часть интерфейса, а её определение - детали реализации. Клиенты обладают информацией только об интерфейсе, и ничего сверх того, что специфицирует и гарантирует интерфейс, им не известно и не должно быть известно.


Ещё раз повторяю - только в стране сказочных фей.

Меня не очень интересует "точка зрения только клиента". 

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

Однако, ваш собственный проект - многоярусный, многоэтажный, многослойный, который помимо вас пилит целая команда - там одной лишь инкапсуляции недостаточно.
Так или иначе, но вам придется заглядывать и на более нижние, и на более верхние этажи.

Меня интересует точка зрения разработчика, которому нужно поддерживать сложный командный проект на протяжении времени.

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

Добавлено @ 20:18
Цитата(kemiisto @  10.9.2014,  19:21 Найти цитируемый пост)
Прототип своих намерений не замалчивает. 


Я хочу что бы вы прочитали текст. И сказали мне, какие мысли вкладывал программист в эти строки:

Код

voo foo(const some& obj);

voo bar(const some* obj);

voo baz(int index);


Я приведу вам пример:

функция baz:
Что делает - очно не ясно. Но судя по наименованию (foo/bar/baz/etc) - просто маленький демонстрационный пример.
Если автор не г_о_в_н_о_кодер, значит индекс с которым она работает - реально может быть отрицательным числом. 
Функция может перетереть свой формальный параметр, а значит не дает никаких строгих гарантий.

Теперь ваша очередь. 
Вам нужно просто рассказать о том, что по вашему хотел сделать программист.

Это сообщение отредактировал(а) Lukkoye - 10.9.2014, 20:20
PM MAIL   Вверх
sQu1rr
Дата 10.9.2014, 21:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(Lukkoye @  10.9.2014,  20:12 Найти цитируемый пост)
Теперь ваша очередь. 
Вам нужно просто рассказать о том, что по вашему хотел сделать программист.

Программист хотел доказать свою точку зрения 3мя демонстраивными функциями, не понимая, что спор о совершенно разных вещях. Его породило ваше высказывание:
Цитата(Lukkoye @  10.9.2014,  20:12 Найти цитируемый пост)
Это действительно не касается вызывающей стороны, несчитая того, 
что теряется информация о том, будет ли вызываемая сторона перетирать данные, или же использовать их только для чтения.

после которого уже 2 страницы идет обсуждение того, что эта точка зрения не верна (вы же сами указали "со стороны клиента").

Стоило вам написать что то вроде "мне нравится использовать конст как программисто, и считаю, что это делает поддержку большого проекта более понятным и само-документируемым хоть и нарушает принцыпы инкапсуляции, ИМХО" и ничего такого бы небыло.
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 10.9.2014, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(Lukkoye @  10.9.2014,  19:12 Найти цитируемый пост)
Теперь ваша очередь. 

За ссылки и указатели говорить не буду, так как речь не о них. Речь только о передаче по константному значению.

И гляда на функцию baz, объявленную следующим образом,
Код
voo baz(int index);

я могу заключить, что при вызове такой функции в моём клиентском коде как-нибудь так
Код
voo v = baz(i);

фактический параметр i передаcтся по значению, т.е. значение фактического параметра i будет скопировано в значение формального параметра index. Это гарантирует мне, что значение фактического параметра i во время вызова baz() не изменится. И если мне эта гарантия по какой-то причине важна, то у меня в голове сразу складывается следующая картина {предусловие} команда {постусловие}:
Код
{i = a} baz(i) {i = a}

Значение i до и после вызова baz(i) одинаковы, или, иными словами, i является инвариантом данной функции.

Цитата(Lukkoye @  10.9.2014,  19:12 Найти цитируемый пост)
Функция может перетереть свой формальный параметр, а значит не дает никаких строгих гарантий.

Да какого, простите, Вам вообще дела до формального параметра? Каких-таких гарантий мне не даёт функция без index, объявленного как const? Что с const, что без него строго гарантированно
Код
{i = a} baz(i) {i = a}

И баста!

Конечно, на уровне реализации const даёт нам инвариантность формального параметра внутри самой функции
Код
voo baz(const int index)
{
    {index = a} ... {index = a}
}

В принципе я могу понять, зачем это нужно. НО! В интерфейсе const для pass-by-value параметров бессмысленен, так как никаких дополнительных гарантий на уровне интерфейса не даёт. Остаётся только вариант, где в интерфейсе квалификатор const опущен, а в реализации он в наличии, если уж Вам так нужно гарантировать неизменность формального параметра. Но мне такой вариант не нравится из-за несоответствия объявления функции её определению (Полочка №2 из предыдущего сообщения).

Это сообщение отредактировал(а) kemiisto - 10.9.2014, 21:21


--------------------
PM MAIL WWW GTalk Jabber   Вверх
sQu1rr
Дата 10.9.2014, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(kemiisto @  10.9.2014,  19:21 Найти цитируемый пост)
Крайне желательно чтобы интерфейс и реализация соответствовали друг другу.

Не всегда возможно, потому что не нужно
Код

int x(int y = 3);
int x(int y) { ... } // нельзя 2 раза" y = 3"

почему же тогда и const не использовать лишь в одном месте? smile

Это сообщение отредактировал(а) sQu1rr - 10.9.2014, 21:50
PM MAIL Skype GTalk   Вверх
Lukkoye
Дата 10.9.2014, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(sQu1rr @  10.9.2014,  21:09 Найти цитируемый пост)
хоть и нарушает принцыпы инкапсуляции


Дану? Интересно, каким же образом?


Цитата(kemiisto @  10.9.2014,  21:19 Найти цитируемый пост)
За ссылки и указатели говорить не буду, так как речь не о них.


Значит эксперимент не состоялся.

Цитата(kemiisto @  10.9.2014,  21:19 Найти цитируемый пост)
Да какого, простите, Вам вообще дела до формального параметра?


Вы не внимательны.
Я уже писал выше - сопровождение кода.

Это значит не только использовать - но и дорабатывать. В том числе за другими. В том числе другие будут дорабатывать после меня.

Самодокументируемость + гарантии от компилятора, что никто ничайно не напортачит.

 
PM MAIL   Вверх
math64
Дата 11.9.2014, 08:04 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Цитата(Lukkoye @  10.9.2014,  23:10 Найти цитируемый пост)
Цитата(kemiisto @  10.9.2014,  21:19 Найти цитируемый пост)
За ссылки и указатели говорить не буду, так как речь не о них.


Значит эксперимент не состоялся.

Раз Вы настаиваете на использовании const, то должны требовоать const и с указателями:
Код

voo bar(const some* const obj);
voo baz(const int index);

Такое компилятор вроде тоже сожрёт (не проверял), хотя смысла особого нет:
Код

voo foo(const some& const obj);

А вообще Ваш спор бессмысленен,  аргументы строн понятны, разве что кто-то найдёт пример вредности такого использования const в С++.

Это сообщение отредактировал(а) math64 - 11.9.2014, 08:24
PM   Вверх
math64
Дата 11.9.2014, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Предлагаю компромисс: использовать const только для параметров, имеющих значения по умолчанию.
Был код:
Код

void func() {
   const int count = 10;
   ...
}

Потребовалась возможность менять count:
Код

void func(const int count = 10) {
   ...
}

PM   Вверх
Lukkoye
Дата 12.9.2014, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(math64 @  11.9.2014,  08:04 Найти цитируемый пост)
Раз Вы настаиваете на использовании const, то должны требовоать const и с указателями:


Верно.
Я так и делаю.

Более того: квалификатор const контекстно зависимый.
Есть ситуации, когда он нужен лишь программисту (и компилятор сделает доп. проверки)

А есть ситуации,когда компилятору критично, квалифицировано ли имя const ?


Я спрашивал ребят на собеседовании: прочтите вслух этот прототип:

Код

void foo(const some& obj);


Многие, очень многие ребята говорили: функция foo, которая ничего не возвращает, в качестве аргумента принимает константную ссылку.

Это не верно. На языке с++ у ссылок вообще нет квалификатора. 

Код

some val;
const some& ref = val;
coust<< std::is_const< decltype(ref) >::val


Результат - ноль.

Если вы попробуете его сделать на шаблонах, то CL (компилятор вижал студии) сделает предупреждение - квалификатор ссылок будет проигнорирован и вы получите мутабельную ссылку.
Компилятор gcc сделает тоже самое, только не сделает предупреждение.

Ну так вот, если вы сделаете:

Код

cout<< std::is_same<void(int), void(const int)>::value


То в качестве результата, вы увидите 1.

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


Резюмируя: вот это тот же самый текст, что я уже сообщил господину Baldina - квалификатор const здесь нужен не компилятору, а человеку, что бы компилятор помог человеку не допустить ничайных ошибок при программировании самой функции.

Мне это видится настолько простым, что мне кажется - ну я просто повторяюсь, а добавить нечего.


Мне очень жаль, что господа влезли в этот диалог, предварительно не прочитав мой диалог с господином Baldina

Добавлено @ 17:03
Цитата(math64 @  11.9.2014,  10:01 Найти цитируемый пост)
Предлагаю компромисс: использовать const только для параметров, имеющих значения по умолчанию.


Противоречит здравому смыслу.

Добавлено @ 17:04
Цитата(math64 @  11.9.2014,  08:04 Найти цитируемый пост)
разве что кто-то найдёт пример вредности такого использования const в С++.


Найдите. Если сможете. Только их нет.

Добавлено @ 17:07
Цитата(math64 @  11.9.2014,  08:04 Найти цитируемый пост)
Такое компилятор вроде тоже сожрёт (не проверял), хотя смысла особого нет:


Так вы проверьте, а потом уже говорите.

Я проверял - квалификатор будет полностью проигнорирован. (cl)

Это сообщение отредактировал(а) Lukkoye - 12.9.2014, 17:09
PM MAIL   Вверх
sQu1rr
Дата 12.9.2014, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(Lukkoye @  12.9.2014,  17:03 Найти цитируемый пост)
Противоречит здравому смыслу.

Не понимаете шуток и намека, как бы пора закруглится (не лично вам, а всем обсуждающим), так как холивар на тему кому как нравится писать код ни к чему хорошему никогда не приводил.
ЗЫ может и не так понял, и мр. math64 действительно считает, что нужно использовать константы с дефолтными параметрами smile
PM MAIL Skype GTalk   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0909 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.