Re[3]: А как насчет [[nodiscard]]?
От: so5team https://stiffstream.com
Дата: 12.08.25 08:18
Оценка:
Здравствуйте, serg_joker, Вы писали:

S>>А вот каково ваше отношение к [[nodiscard]]?

_>Так очевидно же. nodiscard же только генерирует предупреждения в случае чего, а предупреждения "мы" игнорируем.

Чего-то подобного я и ожидаю, но хотелось бы все-таки послушать начальника транспортного цеха...

PS. Сам уже не понимаю как мы до C++17 без этого атрибута жили. Благо компиляторы позволяли его использовать даже в рамках C++11 и C++14.
Re[10]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:03
Оценка:
Здравствуйте, serg_joker, Вы писали:

_>Какие "модные" практики ты видишь такие, что ухудшают качество программистов? Именно практики как таковые, а не их догматическое и чисто формальное использование. Вот так, чтоб практику отменить — и программисты стали лучше.


Ну, например, сейчас больше принято полагаться на тестовое покрытие как критерий корректности кода, чем на какое-либо умственное обоснование. Что приводит к утрате умения рассуждать о корректности кода головой (и заодно снижает степень понимания кода, как своего, так и чужого, и степень понимания используемого API).

Повсеместная практика code review двояка по последствиям. С одной стороны, это хорошо, если код посмотрит другая пара глаз (хотя зачастую ревьювер смотрит код весьма формально, у него и своей работы полно). С другой, это задерживает путь прохождения изменений в репозиторий. Автор коммита вынужден, в ожидании ревью, переключаться на другие задачи. Это рассеивает внимание.

Ну и т.д. Я описал общее ощущение, к серьёзной дискуссии на эту тему я не готов.

Pzz>>Опенсорс бывает разный. У libtiff огромная пользовательская база, и написан он вполне приличным и уважаемым человеком. А код там такой, что хочется его развидеть, пока глаза не отвалились.

_>Ну вот я его заверну аккуратно, чтобы ворнингами не сыпало, и буду пользоваться. Большая пользовательская база такой низкоуровневой хрени — это уже некая гарантия качества (на уровне предоставляемого функционала). Что там внутри меня мало интересует до тех пор, пока мне не нужно будет колупаться в исходниках.

Его кормят снаружи данными в весьма сложном и нетривиальном формате. Тебе его придется в контейнер обернуть, чтобы быть уверенным, что он в тебя не выстрелит.
Re[11]: Имя истинного врага - миссионеры.
От: so5team https://stiffstream.com
Дата: 12.08.25 09:11
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>как критерий корректности кода, чем на какое-либо умственное обоснование


А это вообще как?

Некто alpha21264 или Pzz порассуждал, начирикал что-то на бумажке и заключил "код корректен"?

Или же это "умственное обоснование" должно быть как-то формально быть записано, да еще и так, чтобы проходить хоть какую-то верификацию.
Re[10]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:16
Оценка: +2
Здравствуйте, so5team, Вы писали:

Pzz>>Ну а как люди пишут крупные системы на JS или Питоне? Там с проверками еще сильно хуже.


S>С какими именно проверками?

S>Так-то JS и Python -- это языки со строгой типизацией, в отличии от C или C++.
S>В них по ошибке строку невозможно выдать за double.

JS-то, как раз, без проблем даст сложить строку с числом
Питон да, не даст.

Но оба языка дадут положить в массив или словарь значение неподходящего типа (например, по ошибке, не поле какого-то объекта, а ведь объект целиком). И выстрелит это в момент использования.

S>А именно крупные системы пишут с трудом и за счет тотального тестирования. Не зря же сама мода на unit-тестирование в индустрию пришла из extreme programming, который возник из опыта разработки большого проекта на динамически-типизированном SmallTalk.


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

Я к тому, что всяческие статические проверки — это хорошо. Но не надо по их поводу истерику устраивать.

Кстати, моё личное мнение: динамически типизованные языки плохо подходят для первоначального обучения программированию. Статическая типизация не только следит за руками, но еще и приучает систематически думать наперёд. Если начинать с динамически типизованного языка, в котором "всё можно", этот навык не развивается.
Используйте годные ЯП
От: hi_octane Беларусь  
Дата: 12.08.25 09:18
Оценка:
A>Допустим у нас есть несколько (ну допустим пять) величин: метры, килограммы, секунды, ньютоны и джоули.
A>Да, их нельзя складывать с друг с другом. Но их можно(нужно) умножать и делить.
A>Таким образом, чтобы написать формулу, которая содержит три величины, нам нужно иметь 3*(5+1)*(5+1) типов данных.
A>То есть 36 типов для результатов умножения (килограмм*метр),
A>И 2*36 типов для деления килограмм/метр и метр/килограмм.
A>То есть, что-то около сотни типов. (Точная цифра =108)

Вместо тысячи слов "почему нельзя", всё сделал Oyster на Nemerle ещё в 2006-м:

Возможности:
1. Независимые типы данных, такие как mass и length. Присвоить один другому нельзя — будет ошибка компиляции.
2. Автоматическое конвертирование величин одной и той же размерности из одной системы единиц в другую. К примеру, присвоив килограммам один грамм, в результирующей переменной (si::mass) обнаружим 0.001. Вычисление коэффициентов преобразования производится в compile time.
3. Контроль за корректностью формул со стороны компилятора. Так, если ускорению попытаться присвоить результат деления длины на время, возникнет ошибка компиляции. С моей точки зрения, это наиболее важное свойство моего кода. Особенно это заметно на трехэтажных формулах, где очень легко потерять из виду, какая же в результате получается размерность. В случае использования моего кода подобного рода ошибки полностью исключаются.


Пример:

def m3 = 1 g;
def m4 = Si.Mass(m1);

WriteLine($"Mass in SI: $m4, in CGS: $m3");

def x1 = Si.Area(1 cm * 10 m);

WriteLine($"Area of 1 cm * 10 m = $x1 m")

Отредактировано 12.08.2025 9:22 hi_octane . Предыдущая версия . Еще …
Отредактировано 12.08.2025 9:20 hi_octane . Предыдущая версия .
Re[12]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:21
Оценка: +2
Здравствуйте, so5team, Вы писали:

Pzz>>как критерий корректности кода, чем на какое-либо умственное обоснование


S>А это вообще как?


S>Некто alpha21264 или Pzz порассуждал, начирикал что-то на бумажке и заключил "код корректен"?


Давай так. Или ты не будешь хамить. Или я не буду с тобой разговаривать.

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

S>Или же это "умственное обоснование" должно быть как-то формально быть записано, да еще и так, чтобы проходить хоть какую-то верификацию.


Мне как-то помнится пришлось начальника припрячь оторваться от его начальничьих дел и выслушать моё формальное доказательство сложного куска кода. Но это хорошо, что под рукой был человек с математическим образованием, способный поддерживать разговор на таком уровне.
Re[11]: Имя истинного врага - миссионеры.
От: serg_joker Украина  
Дата: 12.08.25 09:23
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Ну и т.д. Я описал общее ощущение, к серьёзной дискуссии на эту тему я не готов.

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

Pzz>Его кормят снаружи данными в весьма сложном и нетривиальном формате. Тебе его придется в контейнер обернуть, чтобы быть уверенным, что он в тебя не выстрелит.

Убедил, всеми силами буду стараться держаться от него подальше
Re[11]: Имя истинного врага - миссионеры.
От: so5team https://stiffstream.com
Дата: 12.08.25 09:26
Оценка: +1
Здравствуйте, Pzz, Вы писали:

S>>Так-то JS и Python -- это языки со строгой типизацией, в отличии от C или C++.

S>>В них по ошибке строку невозможно выдать за double.

Pzz>JS-то, как раз, без проблем даст сложить строку с числом


Я вообще не о том говорил. В C и C++ вы можете скастовать void* к double* и начать работать с double, хотя по факту за void* был спрятан char*.

Pzz>Но оба языка дадут положить в массив или словарь значение неподходящего типа (например, по ошибке, не поле какого-то объекта, а ведь объект целиком). И выстрелит это в момент использования.


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

Pzz>Мой тезис: отсутствие проверок усложняет разработку, но не делает её невозможной.


Pzz>Я к тому, что всяческие статические проверки — это хорошо. Но не надо по их поводу истерику устраивать.


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

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

Что уже странно, по меньшей мере.
Еще более странно, что не расказывают а чем же компенсируют отсутствие такого контроля.

Моя версия, которую, к сожалению, не представляется возможным проверить -- это работа alpha21264 над небольшой и стабильной кодовой базой в небольшой команде. Да еще и, вероятно, в условиях, когда сама прикладная задача достаточно старая и хорошо изученная. И в которой, могу предположить, математика и физика на пару порядков важнее чем код, в который превращаются итоговые формулы.
Re[12]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:26
Оценка:
Здравствуйте, serg_joker, Вы писали:

Pzz>>Ну и т.д. Я описал общее ощущение, к серьёзной дискуссии на эту тему я не готов.

_>Да я тоже.
_>Ну вот мне кажется, что всё-таки многие практики, будучи приложены к абизянам, безопасность не ухудшают.
_>Не-абизяны на то и не-абизяны, чтобы думать, где чего применять, а где нет. Ну и стараться не работать там, где практики применяются бездумно и формально.

Проблема в том, что человек — существо высокосоциальное. И если он будет работать в команде, состоящей в основном из обезьян, с соответствующими практиками, ну, в конце концов он и сам превратится в обезьяну.

Pzz>>Его кормят снаружи данными в весьма сложном и нетривиальном формате. Тебе его придется в контейнер обернуть, чтобы быть уверенным, что он в тебя не выстрелит.

_>Убедил, всеми силами буду стараться держаться от него подальше

А куда ты денешься, PDF использует евонные кодеки.
Re[2]: А как насчет [[nodiscard]]?
От: alpha21264 СССР  
Дата: 12.08.25 09:27
Оценка: :)))
Здравствуйте, so5team, Вы писали:

S>Из разговра с вами стало понятно, что ряд нововведений в С++ вы считаете бесполезными.


Большую часть того, что появилось после 2010 года.
Если уже даже сам Страуструп говорит, что он знает С++ только на 80%...
Керниган говорил Ричи, когда тот предлагал внести в язык очередную фичу, — если тебе нужен PL/1 ты знаешь, где его взять.
Сейчас современный С++ намного превосходит тот самый монстрообразный PL/1.
Это неправильно. Язык должен быть простым, чтобы программист думал не над языком, а над задачей.

S>А вот каково ваше отношение к [[nodiscard]]?


S>Можно предположить, что "нормальные программисты" (tm) никогда не игнорируют возвращаемые функциями/методами значения. И посему [[nodiscard]] -- всего лишь бесполезный "синтаксический оверхэд" (c)


Ну в общем да. Один раз в жизни это предупредит меня об ошибке, а всё остальное время это будет засирать код.
Слова "один раз в жизни" достаточно ярко выделены?

И что мне делать, если мне действительно не нужно возвращаемое значение? Заводить неиспользуемую переменную?
Или есть какое-то специальное слово "мне действительно не нужно возвращаемое значение"?
Писать вот так?

   (void)ваша_дурацкая_функция();


А кроме того, это просто уродливо. Скажите, ну вот зачем тут [[nodiscard]] сразу двое квадратных скобок?!

Течёт вода Кубань-реки куда велят большевики.
Re[13]: Имя истинного врага - миссионеры.
От: so5team https://stiffstream.com
Дата: 12.08.25 09:29
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>Некто alpha21264 или Pzz порассуждал, начирикал что-то на бумажке и заключил "код корректен"?


Pzz>Давай так. Или ты не будешь хамить.


Или вы перестанете выискивать черную кошку в черной комнате.

S>>Или же это "умственное обоснование" должно быть как-то формально быть записано, да еще и так, чтобы проходить хоть какую-то верификацию.


Pzz>Мне как-то помнится пришлось начальника припрячь оторваться от его начальничьих дел и выслушать моё формальное доказательство сложного куска кода. Но это хорошо, что под рукой был человек с математическим образованием, способный поддерживать разговор на таком уровне.


Давайте переведем вашу историю в более содержательное русло.

Вы с помощью некого формального аппарата вывели доказательство корректности кода.
Далее вы устным образом рассказали это доказательство и оно было принято.

Пока все верно?

Если да, то было ли это доказательство зафиксированно в неком виде, позволяющем провести формальную верификацию посредством программных инструментов?
Re[14]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:33
Оценка:
Здравствуйте, so5team, Вы писали:

S>Давайте переведем вашу историю в более содержательное русло.


Давайте.

S>Если да, то было ли это доказательство зафиксированно в неком виде, позволяющем провести формальную верификацию посредством программных инструментов?


Нет.
Re[3]: А как насчет [[nodiscard]]?
От: so5team https://stiffstream.com
Дата: 12.08.25 09:37
Оценка: +2
Здравствуйте, alpha21264, Вы писали:

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


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

A>Ну в общем да. Один раз в жизни это предупредит меня об ошибке, а всё остальное время это будет засирать код.

A>Слова "один раз в жизни" достаточно ярко выделены?

Да.

A>И что мне делать, если мне действительно не нужно возвращаемое значение?


В стиле современного C++ это должно записываться так:
std::ignore = some_func();


Однако, было бы интересно узнать, а в каких-таких ситуациях можно игнорировать помеченное как [[nodiscard]] значение?

Я сходу могу назвать всего две:

1. Когда кто-то бездумно расставил [[nodiscard]]. По принципу "прикажи дураку богу молиться, он и лоб расшибет".
2. В unit-тестах, когда на возникающие ошибки реально пофиг.

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

Но тогда std::ignore как раз указывает, что мы поступаем так намеренно.
Re[15]: Имя истинного врага - миссионеры.
От: so5team https://stiffstream.com
Дата: 12.08.25 09:39
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>Если да, то было ли это доказательство зафиксированно в неком виде, позволяющем провести формальную верификацию посредством программных инструментов?


Pzz>Нет.


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

Упарывание юнит-тестами имеет свои негативные стороны, но оно хотя бы решает проблему подобных проверок без привлечения механизмов автоматической формальной верификации.
Re[12]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:42
Оценка: +1
Здравствуйте, so5team, Вы писали:

Pzz>>JS-то, как раз, без проблем даст сложить строку с числом


S>Я вообще не о том говорил. В C и C++ вы можете скастовать void* к double* и начать работать с double, хотя по факту за void* был спрятан char*.


Не, ну это всё же специально стараться надо. Случайно так не ляпнешь.

Кстати, union — более удобный инструмент, чтобы так насвистеть, чем кастирование через void*

S>Казалось бы, в твоем распоряжении инструмент, который позволяет забесплатно и автоматически снять с тебя нехилый кусок головной боли.

S>Но ты от этого отказываешься, да еще и кичишься этим.

Сколько лет ушло у линуксячего ядра, чтобы наконец вычистить предупреждения? (да и то я не уверен, что их вычистили целиком).

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


Можно чуть-чуть обобщить.

Есть класс задач, в которых именно прикладной уровень обладает высокой степенью сложности. Например, из-за сложной физики-математики, как в вашем примере. Или из-за алгоритмической сложности. Например, задача написания оптимизирующего компилятора. Заметим, в ней именно "математика" сложна.

В таких задачах люди типа даже не Альфы (про него, живого, мы мало чего знаем), а описанной вами чуть выше модели альфы вполне могут работать.

gcc внутри, кстати, примерно так и написан. Но назвать его говнокодом у меня как-то язык не поворачивается. Все-таки, большая часть мировой кодовой базы вполне успешно через него проходит и выдаёт на выходе вполне работоспособный машинный код.
Re[16]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:47
Оценка: +1
Здравствуйте, so5team, Вы писали:

S>А теперь вопрос: через какое-то время после вас этот код был модифицирован Васей Пупкиным. Что поможет Васе понять, что он ничего не поломал?


Да, это болезненный вопрос. К тому же, я имею тенденцию сочетать алгоритмическую сложность с аккуратным оформлением кода. Это наводит Васю Пупкина на (ложную) мысль, что он в этом коде способен разобраться.

Даже рантайм-проверки не помогают. Вася их убирает, когда они срабатывают, скотина такая.

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


Говорят, когда в машинах массво появились ремни безопасности, люди не стали реже гибнуть на дорогах. Люди стали быстрее ездить.

Я не против тестов. Но к ним что-то еще должно прилагаться.
Re[13]: Имя истинного врага - миссионеры.
От: serg_joker Украина  
Дата: 12.08.25 09:51
Оценка:
Здравствуйте, Pzz, Вы писали:

_>>Не-абизяны на то и не-абизяны, чтобы думать, где чего применять, а где нет. Ну и стараться не работать там, где практики применяются бездумно и формально.


Pzz>Проблема в том, что человек — существо высокосоциальное. И если он будет работать в команде, состоящей в основном из обезьян, с соответствующими практиками, ну, в конце концов он и сам превратится в обезьяну.

В целом согласен (с оговорками про высокосоциальность прям каждого индивидума), поэтому выделенная часть. Ну и вообще выбор коллектива — это очень важно. Если есть такая возможность, то с неумными людьми лучше не работать, жизнь слишком коротка для этого. И уж точно не работать, если неумные люди будут активно влиять на то, как придётся тебе. В том числе, и особенно, если неумные люди — начальство.

_>>Убедил, всеми силами буду стараться держаться от него подальше

Pzz>А куда ты денешься, PDF использует евонные кодеки.
Я имел ввиду работу с библиотекой как программист.
Re[13]: Имя истинного врага - миссионеры.
От: so5team https://stiffstream.com
Дата: 12.08.25 09:51
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>Я вообще не о том говорил. В C и C++ вы можете скастовать void* к double* и начать работать с double, хотя по факту за void* был спрятан char*.


Pzz>Не, ну это всё же специально стараться надо. Случайно так не ляпнешь.


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

S>>Казалось бы, в твоем распоряжении инструмент, который позволяет забесплатно и автоматически снять с тебя нехилый кусок головной боли.

S>>Но ты от этого отказываешься, да еще и кичишься этим.

Pzz>Сколько лет ушло у линуксячего ядра, чтобы наконец вычистить предупреждения? (да и то я не уверен, что их вычистили целиком).


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

Pzz>В таких задачах люди типа даже не Альфы (про него, живого, мы мало чего знаем), а описанной вами чуть выше модели альфы вполне могут работать.


Могут. Только если в таких задачах намечается тенденция к росту кодовой базы, то взгляды персонажей вроде Альфы очень быстро приводят ее в состояние говнокода.
Re[14]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:53
Оценка:
Здравствуйте, serg_joker, Вы писали:

_>>>Убедил, всеми силами буду стараться держаться от него подальше

Pzz>>А куда ты денешься, PDF использует евонные кодеки.
_>Я имел ввиду работу с библиотекой как программист.

Других для C/C++ нет. Если понадобиться об TIFF мараться, придётся с этой.
Re[14]: Имя истинного врага - миссионеры.
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 09:57
Оценка:
Здравствуйте, so5team, Вы писали:

Pzz>>Не, ну это всё же специально стараться надо. Случайно так не ляпнешь.


S>Да сколько угодно как только народ начинает пропихивать информацию через void*.

S>Например, если есть callback-и с дополнительным параметром userData, который как раз void* обычно и является.

Хех. Вы не застали времена, когда в UNIX было принято пропихивать информацию через unsigned int.

На VAX-е то он был 32 бита, как и указатель.

Я в те времена писал под MS-DOS. Unsigned int для меня был 16-битным, а указатель, в large модели — 32-битным.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.