в 99% случаях передаваемые параметры не меняются функцией в которую передаются
соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Эту ошибку практически все языки того времени делали. В Java то же самое.
Re: Как можно было так протупить с const параметрами?
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Хорошая идея. Наверное, вряд ли осуществима с учетом количества кода и требований обратной совместимости. В Свифте, кстати, как раз по умолчанию все параметры функции константны.
Патриот здравого смысла
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Отнюдь! Они не меняются функцией вовне, но используются и меняются внутри функции. Возьми стандартную библиотеку — std:for_each, std::copy, std::transform и т.д. почти все входящие параметры используются и меняются внутри функции(ну кроме It::end()). Точно так же и в strcpy, strlen и т.д. Итого: дефолтный const всех бы сильно утомил (ну если нельзя к итератору сделать it++).
Re[2]: Как можно было так протупить с const параметрами?
Здравствуйте, VVV, Вы писали:
VVV>Здравствуйте, Barbar1an, Вы писали:
B>>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
VVV>Отнюдь! Они не меняются функцией вовне, но используются и меняются внутри функции. Возьми стандартную библиотеку — std:for_each, std::copy, std::transform и т.д. почти все входящие параметры используются и меняются внутри функции(ну кроме It::end()). Точно так же и в strcpy, strlen и т.д. Итого: дефолтный const всех бы сильно утомил (ну если нельзя к итератору сделать it++).
Судя по всему, ТС имел ввиду передачу не по значению, но по ссылке
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>соотв нада было вводить не const модификатор, которым теперь всё заср*но
О чем речь вообще?
Практика навешивать `const` на параметры функций, чтобы предотвратить из изменение, существует и в ней есть логика. Но распространена эта практика настолько мало, что можно говорить "этим никто не пользуется".
О каком "всё заср*но" может идти речь в такой ситуации? Где вы такое сумели найти?
Best regards,
Андрей Тарасевич
Re[3]: Как можно было так протупить с const параметрами?
Здравствуйте, vopl, Вы писали:
VVV>>Отнюдь! Они не меняются функцией вовне, но используются и меняются внутри функции. Возьми стандартную библиотеку — std:for_each, std::copy, std::transform и т.д. почти все входящие параметры используются и меняются внутри функции(ну кроме It::end()). Точно так же и в strcpy, strlen и т.д. Итого: дефолтный const всех бы сильно утомил (ну если нельзя к итератору сделать it++).
V>Судя по всему, ТС имел ввиду передачу не по значению, но по ссылке
С чего бы это? У ТСа открытым текстом написано, что речь идет о константности самих параметров, а не о константности того, на что ссылаются ссылки.
А если он "имел в виду" что-то другое, то это никому не интересно. Телепатов нет.
Best regards,
Андрей Тарасевич
Re[2]: Как можно было так протупить с const параметрами?
АТ>Практика навешивать `const` на параметры функций, чтобы предотвратить из изменение, существует и в ней есть логика. Но распространена эта практика настолько мало, что можно говорить "этим никто не пользуется".
АТ>О каком "всё заср*но" может идти речь в такой ситуации? Где вы такое сумели найти?
Да повсюду.
В код-стайлах многих компаний прописано использования конст везде, где это возможно: Blender Unreal Engine Google
Здравствуйте, VVV, Вы писали:
B>>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
VVV>Отнюдь! Они не меняются функцией вовне, но используются и меняются внутри функции. Возьми стандартную библиотеку — std:for_each, std::copy, std::transform и т.д. почти все входящие параметры используются и меняются внутри функции(ну кроме It::end()). Точно так же и в strcpy, strlen и т.д. Итого: дефолтный const всех бы сильно утомил (ну если нельзя к итератору сделать it++).
Это просто плохо написанный код. В нормально написанном коде параметры не изменяются, если надо изменять — заводится отдельная локальная переменная. Дефолтный const утомил бы только плохих программистов.
Re[2]: Как можно было так протупить с const параметрами?
AleksandrN:
B>>в 99% случаях передаваемые параметры не меняются функцией в которую передаются AN>Это ты сейчас об этом знаешь. А в 1972 году Деннису Ритчи и Кену Томпсону это, видимо, было не очевидно.
Мне кажется в 1972 г. никакого модификатора const еще не было.
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Legacy.
Re[3]: Как можно было так протупить с const параметрами?
Здравствуйте, vsb, Вы писали:
vsb>Это просто плохо написанный код. В нормально написанном коде параметры не изменяются, если надо изменять — заводится отдельная локальная переменная. Дефолтный const утомил бы только плохих программистов.
Это стандартная Сишная идеома: параметры передаются по значению и могут использоваться внутри функции, как локальные переменные.
И важно понимать, что значение указателя — это адрес некоей памяти, а не содержимое этой памяти.
Re[3]: Как можно было так протупить с const параметрами?
Здравствуйте, vopl, Вы писали:
VVV>>Отнюдь! Они не меняются функцией вовне, но используются и меняются внутри функции. Возьми стандартную библиотеку — std:for_each, std::copy, std::transform и т.д. почти все входящие параметры используются и меняются внутри функции(ну кроме It::end()). Точно так же и в strcpy, strlen и т.д. Итого: дефолтный const всех бы сильно утомил (ну если нельзя к итератору сделать it++).
V>Судя по всему, ТС имел ввиду передачу не по значению, но по ссылке
А это бы запутало сильно — по умолчанию по значению не const, а по ссылке (или по указателю?) — const
Здравствуйте, vsb, Вы писали:
vsb>Это просто плохо написанный код. В нормально написанном коде параметры не изменяются, если надо изменять — заводится отдельная локальная переменная. Дефолтный const утомил бы только плохих программистов.
Здравствуйте, Pzz, Вы писали:
vsb>>Это просто плохо написанный код. В нормально написанном коде параметры не изменяются, если надо изменять — заводится отдельная локальная переменная. Дефолтный const утомил бы только плохих программистов.
Pzz>Это стандартная Сишная идеома: параметры передаются по значению и могут использоваться внутри функции, как локальные переменные.
Я знаю си, это в любом языке работает так же. Это не меняет моего мнения. Современный код вообще должен быть в основном иммутабельным. Мутабельная переменная это должно быть, ну не исключение, но точно не большинство кода.
Вот открываю рандомный кусок в nginx-е. Ни параметры не меняются, ни 2 локальные переменные не меняются. Это норма.
Re[4]: Как можно было так протупить с const параметрами?
Здравствуйте, Marty, Вы писали:
vsb>>Это просто плохо написанный код. В нормально написанном коде параметры не изменяются, если надо изменять — заводится отдельная локальная переменная. Дефолтный const утомил бы только плохих программистов.
M>Аргументировать будешь?
Я не знаю, как это аргументировать. Можешь считать это моим наблюдением, что хороший код пишется в стиле, в котором переменные не меняются. А плохой код пишется в стиле, в котором переменные постоянно меняются. Это чем-то похоже на использование goto. В плохом коде goto используется, в хорошем коде goto используется, ну разве что в C для очистки ресурсов, за неимением лучшего.
Я так скажу. Чем больше изменяемых переменных, тем сложней понимать этот код. Поэтому изменяемых переменных должно быть как можно меньше. Делать хаскель из С я не предлагаю, во всём должна быть мера. Но неизменяемых переменных должно быть больше, чем изменяемых. И внимание читателя должно быть обращено именно на изменяемые переменные. Поэтому концепция "const по умолчанию" является правильной.
Здравствуйте, vsb, Вы писали:
Pzz>>Это стандартная Сишная идеома: параметры передаются по значению и могут использоваться внутри функции, как локальные переменные.
vsb>Я знаю си, это в любом языке работает так же. Это не меняет моего мнения. Современный код вообще должен быть в основном иммутабельным. Мутабельная переменная это должно быть, ну не исключение, но точно не большинство кода.
Ну во-первых, не в любом. Это — некоторое изобретение Си, передавать параметры всегда по значению и только по значению. До Си параметры как только не передавались. Вплоть до чрезвычайно сложного и непонятного механизма передачи параметров "по имени" в Algol-60, где если функции передается какая-то переменная, как один из параметров, и выражение, содержащее эту переменную, как другой из параметров, то если функция меняет значение этой переданной ей переменной, то и выражение тоже пересчитывается.
vsb>Вот открываю рандомный кусок в nginx-е. Ни параметры не меняются, ни 2 локальные переменные не меняются. Это норма.
Ты учти еще такую вещь, что компилятор 70-х, если ты заведешь лишнюю переменную, он ведь по-настоящему ее заведет. Не то, что нынешний, который проанализирует, что время фактической жизни переменной — это от сих и до сих, и вне этого интервала переиспользует отведенную на нее память или регистр.
Да даже и до сих пор, слишком много локальных переменных сбивает с толку аллокатор регистров в компиляторе, что отнюдь не увеличивает качество кодогенерации.
Да, в 95% случаев разница в эффективности получающегося машинного кода не имеет особого значения, и лучше писать, как понятно. Но для остальных 5% случаев надо все-таки уметь писать хорошо.
Re[5]: Как можно было так протупить с const параметрами?
Здравствуйте, vsb, Вы писали:
M>>Аргументировать будешь?
vsb>Я не знаю, как это аргументировать. Можешь считать это моим наблюдением, что хороший код пишется в стиле, в котором переменные не меняются. А плохой код пишется в стиле, в котором переменные постоянно меняются.
Ну, чисто твоя имха, не более. С которой я не согласен
vsb>Это чем-то похоже на использование goto. В плохом коде goto используется, в хорошем коде goto используется, ну разве что в C для очистки ресурсов, за неимением лучшего.
Ничем не похоже. Более того, без всякого goto можно написать плохой код, не используя при этом изменение параметров функций
vsb>Я так скажу. Чем больше изменяемых переменных, тем сложней понимать этот код. Поэтому изменяемых переменных должно быть как можно меньше. Делать хаскель из С я не предлагаю, во всём должна быть мера. Но неизменяемых переменных должно быть больше, чем изменяемых. И внимание читателя должно быть обращено именно на изменяемые переменные. Поэтому концепция "const по умолчанию" является правильной.
Неизменяемые переменные вообще не нужны, это просто "синтаксический" сахар. Но это не про параметры. А про параметры — вызывающему коду должно быть насрать (если мы еще говорим о передаче по значению) что происходит внутри функции. А если тупо поклоняться const параметрам и напихивать const везде в сигнатуры функций, то это накладывает ограничения на реализацию функций, чего вообще-то быть не должно. В принципе, конечно, при необходимости можно прототип поправить, кроме пересборки зависимостей ничего страшного не должно произойти, но всё равно это попахивает
Здравствуйте, vsb, Вы писали:
vsb>Я знаю си, это в любом языке работает так же. Это не меняет моего мнения. Современный код вообще должен быть в основном иммутабельным. Мутабельная переменная это должно быть, ну не исключение, но точно не большинство кода.
Не в любом. В твоей джаве все по ссылкам передается, и вот там, да, const имеет некоторый смысл. Ну и, я не помню, как там в джаве, но если в плюсах передавать указатель на интерфейс, да или просто на объект, то все его вызываемые методы должны быть const, если указатель объявлен как const. Это уже прорастает в интерфейс объекта. Особенно это весело, если это интерфейс, там обычно методы const'ом не обмазывают.
vsb>Вот открываю рандомный кусок в nginx-е. Ни параметры не меняются, ни 2 локальные переменные не меняются. Это норма.
Там две переменные, которые константы, считай, и вполне можно обойтись и без них. А то, что по указателю — меняется. А вот указатель сам — не const, хотя можно было бы так сделать (но зачем? Если ты его в функции случайно поменяешь — а поменять там, кроме как на ноль — особо и не на что — и сразу seg fault при повторном использовании, а если после использования — то вообще и не заметишь). И буквально одной функцией выше — там всё меняется — https://github.com/nginx/nginx/blob/f7ea8c76b55f730daa3b63f5511feb564b44d901/src/http/ngx_http_request_body.c#L820. Такое впечатление, что ты этот случайно тыкнутый фрагмент долго и тщательно выбирал
Здравствуйте, Marty, Вы писали:
vsb>>Я знаю си, это в любом языке работает так же. Это не меняет моего мнения. Современный код вообще должен быть в основном иммутабельным. Мутабельная переменная это должно быть, ну не исключение, но точно не большинство кода.
M>Не в любом. В твоей джаве все по ссылкам передается, и вот там, да, const имеет некоторый смысл.
В жаве нет передачи по ссылке. В жаве исключительно передача по значению. В жаве ссылок в языке вообще нет, только указатели.
> Ну и, я не помню, как там в джаве, но если в плюсах передавать указатель на интерфейс, да или просто на объект, то все его вызываемые методы должны быть const, если указатель объявлен как const. Это уже прорастает в интерфейс объекта. Особенно это весело, если это интерфейс, там обычно методы const'ом не обмазывают.
В С++ это выглядит как my_class * const mc.
vsb>>Вот открываю рандомный кусок в nginx-е. Ни параметры не меняются, ни 2 локальные переменные не меняются. Это норма. M>Там две переменные, которые константы, считай, и вполне можно обойтись и без них. А то, что по указателю — меняется. А вот указатель сам — не const, хотя можно было бы так сделать (но зачем? Если ты его в функции случайно поменяешь — а поменять там, кроме как на ноль — особо и не на что — и сразу seg fault при повторном использовании, а если после использования — то вообще и не заметишь). И буквально одной функцией выше — там всё меняется — M> https://github.com/nginx/nginx/blob/f7ea8c76b55f730daa3b63f5511feb564b44d901/src/http/ngx_http_request_body.c#L820. Такое впечатление, что ты этот случайно тыкнутый фрагмент долго и тщательно выбирал
Не выбирал. В твоем примере параметры не меняются. Из четырех локальных переменных только 1 меняется.
Если я непонятно выражаюсь, под константными параметрами я имею в ввиду исключительно неизменяемость самой переменной. А не тех данных, куда она указывает. Константность тех данных, куда она указывает, это вопрос более сложный. От С этого требовать точно не стоит.
В C++ вопрос стоит с какой-то стороны проще, т.к. там часто применяются ссылки, которые неизменяемы по своей природе.
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Здравствуйте, Barbar1an, Вы писали:
B>>соотв нада было вводить не const модификатор, которым теперь всё заср*но
АТ>О чем речь вообще?
АТ>Практика навешивать `const` на параметры функций, чтобы предотвратить из изменение, существует и в ней есть логика. Но распространена эта практика настолько мало, что можно говорить "этим никто не пользуется".
АТ>О каком "всё заср*но" может идти речь в такой ситуации? Где вы такое сумели найти?
дело в том что есть случаи когда вы вынуждены использовать конст, например чтобы литералы передавать без обворачивания в конструктор, классика — std::string
а заюзав одном есте такой конст вас потом компилятор заставит в кучу других методов напихать их
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
По умолчанию параметры передаются по значению, то есть копируются, а это еще большая "константность", нежели просто указание const. То есть есть передача по ссылке, по константной ссылке и по значению. И последнее — самое иммутабельное, иммутабельней некуда просто. Передавать по const-значению (int foo(const int arg)) — это просто синтаксический оверхед, простите, не дающий никакой безопасности. Ну, разве что спасёт от описки неопытного программиста. Ты предлагаешь запретить менять формальные параметры? А зачем? С/C++ — не функциональный язык, незачем подражать парадигмам другого языка. Кстати, а как смувить формальный параметр, обозначенный как const? Объявлять его mutable?
Re[2]: Как можно было так протупить с const параметрами?
Здравствуйте, Went, Вы писали:
W>Здравствуйте, Barbar1an, Вы писали:
B>>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
W>По умолчанию параметры передаются по значению, то есть копируются, а это еще большая "константность", нежели просто указание const. То есть есть передача по ссылке, по константной ссылке и по значению. И последнее — самое иммутабельное, иммутабельней некуда просто. Передавать по const-значению (int foo(const int arg)) — это просто синтаксический оверхед, простите, не дающий никакой безопасности. Ну, разве что спасёт от описки неопытного программиста. Ты предлагаешь запретить менять формальные параметры? А зачем? С/C++ — не функциональный язык, незачем подражать парадигмам другого языка. Кстати, а как смувить формальный параметр, обозначенный как const? Объявлять его mutable?
передача по значению совсем не "самое иммутабельное, иммутабельней некуда просто", все зависит от того какой у вас там copy и move конструкторы
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[2]: Как можно было так протупить с const параметрами?
Здравствуйте, Went, Вы писали:
W>По умолчанию параметры передаются по значению, то есть копируются, а это еще большая "константность", нежели просто указание const. То есть есть передача по ссылке, по константной ссылке и по значению. И последнее — самое иммутабельное, иммутабельней некуда просто. Передавать по const-значению (int foo(const int arg)) — это просто синтаксический оверхед, простите, не дающий никакой безопасности. Ну, разве что спасёт от описки неопытного программиста. Ты предлагаешь запретить менять формальные параметры? А зачем? С/C++ — не функциональный язык, незачем подражать парадигмам другого языка. Кстати, а как смувить формальный параметр, обозначенный как const? Объявлять его mutable?
смысл такой же как и объявлять любую переменную const
foo(const int i) // объявляем, что i меняться нигде дальше не будет
{
const int k = i; // тоже самое.
... // и тут кода на тыщу строк, чтобы сполна могли насладиться бонусами const
}
А то, что нельзя мувать const объекты — это уже явная бага C++. Впрочем она растёт из "use after move".
Re[7]: Как можно было так протупить с const параметрами?
Здравствуйте, vsb, Вы писали:
M>>Не в любом. В твоей джаве все по ссылкам передается, и вот там, да, const имеет некоторый смысл.
vsb>В жаве нет передачи по ссылке. В жаве исключительно передача по значению. В жаве ссылок в языке вообще нет, только указатели.
Ну, ссылка или указатель — не суть, эти различия только в плюсах, где есть между ними различие. Мне почему-то казалось, что в джаве указатели на объекты именуются ссылками, вроде их то так то этак именуют там
>> Ну и, я не помню, как там в джаве, но если в плюсах передавать указатель на интерфейс, да или просто на объект, то все его вызываемые методы должны быть const, если указатель объявлен как const. Это уже прорастает в интерфейс объекта. Особенно это весело, если это интерфейс, там обычно методы const'ом не обмазывают.
vsb>В С++ это выглядит как my_class * const mc.
Что именно в C++ так выглядит? Что за "это"?
vsb>Не выбирал. В твоем примере параметры не меняются. Из четырех локальных переменных только 1 меняется.
Ну ок, тут ты прав
vsb>Если я непонятно выражаюсь, под константными параметрами я имею в ввиду исключительно неизменяемость самой переменной. А не тех данных, куда она указывает. Константность тех данных, куда она указывает, это вопрос более сложный. От С этого требовать точно не стоит.
Контролировать неизменяемость передаваемой переменной нафик не нужно, так как это вылезает в публичный контракт, которому, по большому счету, должно быть пофиг на то, что делается внутри функции. Было бы полезно, если бы внутри реализации был бы механизм, позволяющий сказать, что все параметры функции — константные, кроме указанных явно.
Здравствуйте, Barbar1an, Вы писали:
B>дело в том что есть случаи когда вы вынуждены использовать конст, например чтобы литералы передавать без обворачивания в конструктор, классика — std::string
Это если ты std::string по ссылке передаешь, если по значению — не нужен никакой конст
B>а заюзав одном есте такой конст вас потом компилятор заставит в кучу других методов напихать их
Обычно это происходит, когда ты методы помечаешь, как конст
Здравствуйте, Marty, Вы писали:
M>>>Не в любом. В твоей джаве все по ссылкам передается, и вот там, да, const имеет некоторый смысл.
vsb>>В жаве нет передачи по ссылке. В жаве исключительно передача по значению. В жаве ссылок в языке вообще нет, только указатели.
M>Ну, ссылка или указатель — не суть, эти различия только в плюсах, где есть между ними различие. Мне почему-то казалось, что в джаве указатели на объекты именуются ссылками, вроде их то так то этак именуют там
Ну я считаю, что ссылка это неизменяемый указатель, что-то вроде alias-а. А так ты прав, именуют по-разному. Хотя судя по тому, что в языке есть NullPointerException, а не NullReferenceException, я лично считаю, что официально их следует называть указателями. С другой стороны арифметики указателей в жаве тоже нет. В общем не суть, но ссылки/указатели жавы на указатели C++ похожи больше, чем на ссылки C++.
>>> Ну и, я не помню, как там в джаве, но если в плюсах передавать указатель на интерфейс, да или просто на объект, то все его вызываемые методы должны быть const, если указатель объявлен как const. Это уже прорастает в интерфейс объекта. Особенно это весело, если это интерфейс, там обычно методы const'ом не обмазывают.
vsb>>В С++ это выглядит как my_class * const mc.
M>Что именно в C++ так выглядит? Что за "это"?
Объявление неизменяемого параметра функции. Ну или объявление неизменяемой переменной (не нравится мне это словосочетание, немасляное масло, но называть это "константой", наверное, тоже не корректно). Т.е. сама переменная mc не изменяема, но при этом можно вызывать неконстантные методы класса my_class.
vsb>>Если я непонятно выражаюсь, под константными параметрами я имею в ввиду исключительно неизменяемость самой переменной. А не тех данных, куда она указывает. Константность тех данных, куда она указывает, это вопрос более сложный. От С этого требовать точно не стоит.
M>Контролировать неизменяемость передаваемой переменной нафик не нужно, так как это вылезает в публичный контракт, которому, по большому счету, должно быть пофиг на то, что делается внутри функции. Было бы полезно, если бы внутри реализации был бы механизм, позволяющий сказать, что все параметры функции — константные, кроме указанных явно.
Не понимаю, почему это вылезает в публичный контракт. Это имеет значение только для реализации функции, меняет она что-то или нет. Если в С++ это не так, это баг.
Но вообще, похоже, что ты не прав. Такая программка в онлайн-компиляторе никаких предупреждений не выдаёт.
Здравствуйте, Barbar1an, Вы писали: B>передача по значению совсем не "самое иммутабельное, иммутабельней некуда просто", все зависит от того какой у вас там copy и move конструкторы
Тогда и неявное указание константности на передаваемые значения тоже не гарантирует никакой иммутабельности, все зависит от того, сколько вы mutable и const_cast-ов влупили во внешне константные методы передаваемого объекта.
Re[3]: Как можно было так протупить с const параметрами?
Здравствуйте, sergii.p, Вы писали:
SP>смысл такой же как и объявлять любую переменную const...
Ну, нормальный программист не пишет код на тыщу строк, а если это где-то критично, и он почему-то путается, в тех местах можно уже и объявить константный параметр или даже константную ссылку на параметр, если не хочется детали в интерфейс функции тянуть.
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
По сравнению с постулатом что в программе нет ошибок, а если есть то виноват только программист и это UB — не константные параметры по умолчанию не значительная мелочь.
Re[3]: Как можно было так протупить с const параметрами?
Здравствуйте, DiPaolo, Вы писали:
АТ>>Практика навешивать `const` на параметры функций, чтобы предотвратить из изменение, существует и в ней есть логика. Но распространена эта практика настолько мало, что можно говорить "этим никто не пользуется".
АТ>>О каком "всё заср*но" может идти речь в такой ситуации? Где вы такое сумели найти?
DP>Да повсюду.
DP>В код-стайлах многих компаний прописано использования конст везде, где это возможно:
Для этого нужно более точно определить, что имеется в виду под "везде, где это возможно". Возможно, что авторы этих рекомендаций не совсем хорошо себе представляли всю полноту диапазона таких "возможностей".
DP>Blender DP>Unreal Engine DP>Google
Из приведенных вам ссылок только первая относится к рассматриваемому вопросу. Во второй ничего на эту тему вообще нет. В третьей же рекомендуется полностью обратное (!): "For a function parameter passed by value, const has no effect on the caller, thus is not recommended in function declarations".
DP>Вот рекомендации от Страуструпа и Саттера в C++ Core Guidelines: DP>https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#con-constants-and-immutability
И здесь я навскидку не вижу абсолютно ничего, относящегося к рассматриваемому вопросу.
Напомню, что речь не о `const` вообще и не о const-квалификации путей доступа через указатели или ссылки, а именно об объявлении самих параметров функций как `const`. То есть речь идет именно о о (пример из вашей первой ссылки):
oid func(const float param) { ... }
Еще раз: это разумно, но практически этим никто не пользуется. Что, кстати, и демонстрируют приведенные вами ссылки. А гугловский гайд даже открытым текстом призывает не делать этого.
Best regards,
Андрей Тарасевич
Re[4]: Как можно было так протупить с const параметрами?
Здравствуйте, Pzz, Вы писали:
B>>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Pzz>Legacy.
Постоянно слышу про «легаси», когда возникает вопрос, почему было принято самое корявое и уродливое из всех возможных решений.
Как бы, язык давно уже разделился на C++14, C++17, C++20. Вполне можно было бы ввести что-то типа 'use strict' #pragma strict.
Do you want to develop an app?
Re: Как можно было так протупить с const параметрами?
Здравствуйте, Barbar1an, Вы писали:
B>в 99% случаях передаваемые параметры не меняются функцией в которую передаются B>соотв нада было вводить не const модификатор, которым теперь всё заср*но, а сделать всё по умолчанию const, а то что меняется указывать через например mutable
Засрано, факт. Во многих местах код, написанный без этого, просто не пропустят. Считается, что он от этого «лучше». Но тогда возникает закономерный вопрос, почему в этом языке по умолчанию код получается «хуже».
Do you want to develop an app?
Re[2]: Как можно было так протупить с const параметрами?
W>То есть есть передача по ссылке, по константной ссылке и по значению. И последнее — самое иммутабельное, иммутабельней некуда просто. Передавать по const-значению (int foo(const int arg)) — это просто синтаксический оверхед, простите, не дающий никакой безопасности. Ну, разве что спасёт от описки неопытного программиста. Ты предлагаешь запретить менять формальные параметры? А зачем?
Ситуация, когда изменяется входящий параметр, достаточно нелогичная. Входящие параметры по значению — это, считай, настройки, конфиг. И менять их — весьма нетипичная и даже в некоторой степени является воркэраундом. Надо тебе что-то повычислять — заведи свою переменную, куда скопируй входное значение. А потом меняй его как хочешь. Изменение входящих параметров 100% ведет к багам и это является заложенной тайм-бомбой.
По идее, все параметры функции — это "настройки", и логически они не должны меняться. Просто из-за особенностей синтаксиса и слабого развития вычислительных мощностей 50 лет назад приходилось экономить и передавать значения по ссылке или указателю, чтобы избежать лишних копирований, и иметь возможность вернуть 2 и более значений, а также не копировать при возвращении значения.
Можно было бы возвращать несколько значений (tuple), и не исхитрялись бы со всякими там двойными указателями и in/out параметрами. Не надо было бы думать об оптимизации — и пихали бы все по значению — и пофиг на копирование.
Потому что еще раз: логически параметры функции — это ее настройки. Которые логически должны быть константами. Типа, у нас ест функция возведения в степень double pow(int a, int b). По сути, здесь a и b — это настройки, начальные условия для вычислений. Меняться они не должны, потому что это условия вычисления, ну как параметры математической функции.
Вот еще пример, почему не стоит изменять параметры:
RetCode ProcessBuffer(uint8_t *data, int size)
{
// обработали 4 байтаconst auto startCode = getBytes(data, 4);
data += 4;
size -= 4;
...
// а тут новый человек по незнанию/невнимательности и т.д. сделал
// подсчет чек суммы, получив ошибкуconst auto checkSum = calcCheckSum(data, size);
}
RetCode ProcessBuffer(const uint8_t* const data, const int size)
{
auto ptr = data;
auto bytesLeft = size;
// обработали 4 байтаconst auto startCode = getBytes(ptr, 4);
ptr += 4;
bytesLeft -= 4;
...
// делаем подсчет чек-суммы на входящем наборе данныхconst auto checkSum = calcCheckSum(data, size);
}
На практике так конечно никто не пишет )) Но лично я отношусь к входящим параметрам как "к чужому" — не мне их менять, это стартовые условия для вычислений.
Upd под "так" имелось ввиду ставить const перед параметрами по значению для встроенных типов данных. Типа, int pow(const int a, const int b).
vsb>Но вообще, похоже, что ты не прав. Такая программка в онлайн-компиляторе никаких предупреждений не выдаёт.
Да, похоже. Интересно, не знал. Я всегда только ссылки и указуемое константными объявлял, и с подобным не сталкивался.
Но тут другой нюанс. Если мы все параметры в прототипе обмазали const'ами (которые кроме случая ссылок снаружи рояли не играют), а в реализации — убрали эти const (или — наоборот), то хоть с точки зрения компилятора это будет одно и то же, но для человека это будет выглядеть очень по разному, и это плохо.
Ну, и обычно, на самом деле я хоть констами не обмазываюсь, но и параметры не слишком часто изменяю. Но есть некоторые типичные случаи
void traverse_list( List *pHead )
{
for(; pHead; pHead=pHead->next)
{
//...
}
}
void vec_something( int n, const vector &vec )
{
if (vec.empty())
return;
if (n<0)
n = 0;
if (n>=vec.size())
n = vec.size();
//...
}
void str_something( string s )
{
s = trim(s);
s = to_upper(s);
//...
}
Не вижу смысла заводить отдельные переменные в подобных случаях
Здравствуйте, DiPaolo, Вы писали: DP>На практике так конечно никто не пишет )) Но лично я отношусь к входящим параметрам как "к чужому" — не мне их менять, это стартовые условия для вычислений.
Практика С++ подразумевает разные подходы и разные предметные области. Если для вас скопировать какую-то переменную не критично ради лучше читаемости, то в другой предметной области это может очень даже болезненно. А еще есть обобщенный код, и вместо того int size может оказаться T size, которому подставили какого-то монстра с нетривиальным копированием. И вместо мува, мы получим копирование.
Re[5]: Как можно было так протупить с const параметрами?
Здравствуйте, Shtole, Вы писали:
S>Как бы, язык давно уже разделился на C++14, C++17, C++20. Вполне можно было бы ввести что-то типа 'use strict' #pragma strict.
SP>смысл такой же как и объявлять любую переменную const
SP>
SP>foo(const int i) // объявляем, что i меняться нигде дальше не будет
SP>{
SP> const int k = i; // тоже самое.
SP> ... // и тут кода на тыщу строк, чтобы сполна могли насладиться бонусами const
SP>}
SP>
Это намек компилятору, что можно вычислить в компайл-тайм один раз. С параметрами так не получится, они в любом случае живут в рантайме
Здравствуйте, T4r4sB, Вы писали:
SP>>А то, что нельзя мувать const объекты — это уже явная бага C++. Впрочем она растёт из "use after move".
TB>Она растёт из того, что move это не мув, а что-то типа свапа с чистым объектом.
Здравствуйте, DiPaolo, Вы писали:
DP>Ситуация, когда изменяется входящий параметр, достаточно нелогичная. Входящие параметры по значению — это, считай, настройки, конфиг. И менять их — весьма нетипичная и даже в некоторой степени является воркэраундом. Надо тебе что-то повычислять — заведи свою переменную, куда скопируй входное значение. А потом меняй его как хочешь. Изменение входящих параметров 100% ведет к багам и это является заложенной тайм-бомбой.
Вполне логичная. Ок. Это конфиг. Перед использованием заданные конфигом параметры надо проверить, и привести в допустимый диапазон.
void doSomething( string str )
{
str = trim(str);
str = to_upper(str);
str = replace(str,'-','_');
// еще куча вызовов для нормализации заданного аргумента
// колбасим рабочий код тут
}
DP>>На практике так конечно никто не пишет )) Но лично я отношусь к входящим параметрам как "к чужому" — не мне их менять, это стартовые условия для вычислений.
Тут речь шла про применение модификатора конст для входных параметров встроенных типов, типа const int param.
W>Практика С++ подразумевает разные подходы и разные предметные области. Если для вас скопировать какую-то переменную не критично ради лучше читаемости, то в другой предметной области это может очень даже болезненно.
Спасибо, я в курсе
Патриот здравого смысла
Re: Как можно было так протупить с const параметрами?
Здравствуйте. Да, век живи — век учись. Раз такое работает:
#include <iostream>
using namespace std;
struct A
{
void f(const int a);
};
void A::f(int a)
{
a = 5;
cout << "Wow!";
}
int main()
{
A a;
a.f(1);
return 0;
}
То вполне можно было сделать так, что в заголовке константность запрещать (она все равно игнорируется), а в реализации сделать константу по умолчанию, а разрешать менять словом mutable. Но, блин, это ломает обратную совместимость.
Re[4]: Как можно было так протупить с const параметрами?
Здравствуйте, Marty, Вы писали:
S>>Как бы, язык давно уже разделился на C++14, C++17, C++20. Вполне можно было бы ввести что-то типа 'use strict' #pragma strict.
M>Даёшь еще более навороченный и запутанный C++!!!
Это как раз способ распутать. А то задолбали уже всё на легаси сваливать.
Do you want to develop an app?
Re[5]: Как можно было так протупить с const параметрами?
Здравствуйте, Shtole, Вы писали:
S>>>Как бы, язык давно уже разделился на C++14, C++17, C++20. Вполне можно было бы ввести что-то типа 'use strict' #pragma strict.
M>>Даёшь еще более навороченный и запутанный C++!!!
S>Это как раз способ распутать. А то задолбали уже всё на легаси сваливать.
- У нас есть 14 способов сделать одно и то же
...
— Я придумал новый, универсальный способ!!!
ИМХО, на практике будет следующее. Какой-нибудь джун напишет auto size_mutable = size; (ну, чтобы можно было модифицировать, в этом же суть), а потом по невнимательности передаст size_mutable вместо size и... ничего плохого не случится. При первом же прогоне ошибка всплывёт и будет пофикшена. Всё это к реальным ошибкам (порче памяти) имеет мало отношения.
Но я, конечно, отнюдь не против, чтобы все параметры были константными по умолчанию.
Do you want to develop an app?
Re[6]: Как можно было так протупить с const параметрами?
Здравствуйте, Marty, Вы писали:
S>>>>Как бы, язык давно уже разделился на C++14, C++17, C++20. Вполне можно было бы ввести что-то типа 'use strict' #pragma strict.
M>>>Даёшь еще более навороченный и запутанный C++!!!
S>>Это как раз способ распутать. А то задолбали уже всё на легаси сваливать.
M>
M>- У нас есть 14 способов сделать одно и то же
M>...
M>- Я придумал новый, универсальный способ!!!
M>...
M>- У нас есть 15 способов сделать одно и то же
Почему это сработало в Джаваскрипте и не сработает тут? Только без пересказов анекдотов с xkcd, пожалуйста.
Do you want to develop an app?
Re[5]: Как можно было так протупить с const параметрами?
Здравствуйте, Marty, Вы писали:
M>Что ты подразумеваешь под "чистым" объектом?
Для строк — пустую строку, для коллекций — пустую коллекцию. В общем виде — состояние объекта после дефолтного конструктора.
Я вообще не очень представляю, можно ли представить не-надуманный пример объекта, у которого есть мув-конструктор, но нет дефолтного конструктора.
Re[6]: Как можно было так протупить с const параметрами?
Здравствуйте, T4r4sB, Вы писали:
M>>Что ты подразумеваешь под "чистым" объектом?
TB>Для строк — пустую строку, для коллекций — пустую коллекцию. В общем виде — состояние объекта после дефолтного конструктора. TB>Я вообще не очень представляю, можно ли представить не-надуманный пример объекта, у которого есть мув-конструктор, но нет дефолтного конструктора.
Меня смутило
TB>Она растёт из того, что move это не мув, а что-то типа свапа с чистым объектом.
мне казалось, что мув это типа свапа с непроинициализированным объектом
Здравствуйте, Shtole, Вы писали:
S>Как бы, язык давно уже разделился на C++14, C++17, C++20. Вполне можно было бы ввести что-то типа 'use strict'#pragma strict.
У комитета по этому поводу ещё стадия отрицания полностью не прошла.
Ну, по крайней мере, полумеры начали делать, а значит ещё лет 50 и придут к прагмам и ключам компилятора
Re[5]: Как можно было так протупить с const параметрами?
Здравствуйте, DiPaolo, Вы писали:
DP>Ситуация, когда изменяется входящий параметр, достаточно нелогичная. Входящие параметры по значению — это, считай, настройки, конфиг. И менять их — весьма нетипичная и даже в некоторой степени является воркэраундом. Надо тебе что-то повычислять — заведи свою переменную, куда скопируй входное значение. А потом меняй его как хочешь.
Есть типичная ситуация, когда входящий параметр меняется оставаясь "неизменным":
DP> Изменение входящих параметров 100% ведет к багам и это является заложенной тайм-бомбой.
Предположение, что не const переменная не меняется является ошибочным.
И каждый день — без права на ошибку...
Re[5]: Как можно было так протупить с const параметрами?