Re[7]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 12:08
Оценка:
Здравствуйте, B0FEE664, Вы писали:

S>>а можно пожалуйста пример чем соверменный С++ хуже Си в таких проектах

BFE>Тут дело не в языке, а в бюрократии и особых требованиях.
BFE>Например, в авионике это 100% покрытие кода тестами.
BFE>В частности, если у вас есть вызов new, то надо предоставить тест, который обрабатывает исключение бросаемое new при нехватке памяти. И так для каждого встречающегося в коде new, а не в одном каком-то месте. Представляете себе объём работы по написанию тестов? Исходя из этого для многих проектов просто запрещается динамическая аллокация памяти. Соответственно выбрасывается всё, что аллоцирует память, начиная с std::vector ...

Глупости какие. Я например периодически пишу код для МК и использую там на полную удобства C++17 (скоро уже на 20 буду переползать). При этом там естественно нет динамического выделения памяти в принципе.
Re[17]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 12:19
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

DI>>7-8 будет хайлоад, я там выступаю с докладом

НС>Не нашел

Кстати, в контексте данной дискуссии довольно забавно, что там не мало докладов по C++ тематике. Я и не думал, что C++ имеет существенное распространение в данной области за пределами таких специфических монстриков как Гугл, Яндекс и т.п.
Re[32]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 12:22
Оценка:
Здравствуйте, CreatorCray, Вы писали:

Pzz>>В комментарии к функции написать.

CC>Бугага!!!

Давай я попробую вкратце изложить свою позицию.

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

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

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

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

Pzz>> Я серьезно.

CC>Сколько ты лет работаешь в команде?

Это совершенно не имеет отношения к обсуждаемой проблеме. Давай говорить по сути, а не обсуждать личности друг друга.
Re[8]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 12:22
Оценка:
Здравствуйте, Marty, Вы писали:

M>Но вот например, забагованное до нельзя поделие — GCC — написано от и до на чистой сишечке, а качественный компилятор с человеческим лицом (clang/llvm) — на C++


Вообще то gcc уже давно перешли на C++. Ну и да, архитектурно clang конечно на порядки лучше. Только вот при этом он пока является худшим в производительности генерируемого кода среди всех основных компиляторов. Так что я конечно же надеюсь когда-нибудь полностью перейти на него (хороши когда сообщения об ошибках человеческие и всё такое), но до этого времени ещё очень далеко (им ещё работать и работать над оптимизатором).
Re[17]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 12:24
Оценка: +1
Здравствуйте, so5team, Вы писали:

S>И это мы еще не рассматривали такие мощные инструменты для создания абстракций, как классы и шаблоны. Например, как вы в чистом C выразите абстракцию "значение в заданном диапазоне", которая на C++ делается влет простым шаблоном вроде:


Я что-то не понял, а операции + и — для этого constrained_value современный компилятор сам выведет, или их тоже надо руками расписать?
Re[8]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 12:26
Оценка: :)
Здравствуйте, alex_public, Вы писали:

_>Глупости какие. Я например периодически пишу код для МК и использую там на полную удобства C++17 (скоро уже на 20 буду переползать). При этом там естественно нет динамического выделения памяти в принципе.


А что значит, нету в принципе? Ты не используешь слово new, или все твои алгоритмы имеют требования к памяти O(1)?
Re[35]: А С++ то схлопывается...
От: night beast СССР  
Дата: 02.11.19 13:20
Оценка:
Здравствуйте, Pzz, Вы писали:

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


тут в ветке nekocoder уже жаловался на то что ссылку можно инициализировать nullptr.
если бы в параметрах приходящему объекту было прописано требование not_null, то и проблем с поиском бага бы не возникло.
Re[18]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 02.11.19 13:26
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>И это мы еще не рассматривали такие мощные инструменты для создания абстракций, как классы и шаблоны. Например, как вы в чистом C выразите абстракцию "значение в заданном диапазоне", которая на C++ делается влет простым шаблоном вроде:


Pzz>Я что-то не понял, а операции + и — для этого constrained_value современный компилятор сам выведет, или их тоже надо руками расписать?


В том-то и дело, что для простейшего случая это и не нужно. В нем есть операция приведения к типу T, поэтому показанный тривиальный constrained_value можно использовать вот так, например:
my_range get_current_value() {
   my_range raw = read_raw_value(); // Гарантия того, что в raw допустимое значение.
   short tmp = static_cast<short>(raw) * 10; // Вот тут все гарантии потерялись.
   if(specific_moon_phase())
     tmp += 135;
   if(some_time_of_day())
     tmp /= 3;
   return my_range{tmp}; // Здесь появляется гарантия того, что возвращается допустимое значение.
}


Теперь хотелось бы посмотреть на это в чистом С.
Re[19]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 13:50
Оценка: +2
Здравствуйте, so5team, Вы писали:

S>В том-то и дело, что для простейшего случая это и не нужно. В нем есть операция приведения к типу T, поэтому показанный тривиальный constrained_value можно использовать вот так, например:


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

Т.е., если мы выносим такую функцию в интерфейс, скажем, класса, который читает конфигурацию, то тот, кто использует этот класс, должен быть готов, что к нему прилетят исключения, не имеющие в себе никакой информации ни о конфигурационном файле, ни о том, как найти и исправить возникшие проблемы, но зато ссылающиеся на некие низкоуровневые типы, которые читалка конфигирации удосужилась использовать на данном этапе своего развития. Потому что в конечном итоге пользователю надо показать не стек вызовов, а что-нибудь типа "чувак, у тебя в файле myconfig.cfg в 35-й строке какая-то хрень написана, исправь пожалуйста"). И кто-то в пути должен это уметь делать. Причем желательно бы кто-то, кто понимает про конфигурационные файлы, а не тот, кому эти значения на пять этажей выше нужны для работы, и кому все равно, откуда они взялись, лишь бы они были правильными.

S>Теперь хотелось бы посмотреть на это в чистом С.


В C я написал бы явную проверку. И вернул бы явную ошибку. А в Go еще удобнее, я вернул бы результат и ошибку одним махом, там функция может вернуть сразу несколько значений.
Re[20]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 02.11.19 14:03
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>В том-то и дело, что для простейшего случая это и не нужно. В нем есть операция приведения к типу T, поэтому показанный тривиальный constrained_value можно использовать вот так, например:


Pzz>Мне этот код не нравится. Не нравится он мне тем, что из него может прилететь исключение. Причем в этом исключении будет сказано лишь, что оно относится к некоему constrained_value.


Вас куда-то постоянно уносит в сторону. И, складывается ощущение, что это от незнания инструмента о котором вы пытаетесь судить. А может и от специфического опыта.

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

S>>Теперь хотелось бы посмотреть на это в чистом С.


Pzz>В C я написал бы явную проверку.


И после этого вы еще чего-то говорите про человеческий фактор и его влияние?

Pzz>И вернул бы явную ошибку. А в Go еще удобнее, я вернул бы результат и ошибку одним махом, там функция может вернуть сразу несколько значений.


Рискую вас удивить, но в C++ вы запросто можете вернуть, скажем expected, которое будет содержать либо нормальный результат, либо ошибку. Что сильно лучше, чем два значения в Go, одно из которых заведомо некорректно.
Re[21]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 14:27
Оценка: +1
Здравствуйте, so5team, Вы писали:

Pzz>>Мне этот код не нравится. Не нравится он мне тем, что из него может прилететь исключение. Причем в этом исключении будет сказано лишь, что оно относится к некоему constrained_value.


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


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

Говорить об инструменте имеет смысл в контексте решения практических, а не школьных, задач. Если довести ваш пример до нормального состояния, что там был ваш constrained_value, что его не было, разница будет не шибко заметна.

S>Суть constrained_value в том, чтобы содержать заведомо корректное значение. Ответственность за получение этого значения лежит на разработчике. Соответственно, прежде чем поместить что-то в constrained_value вы можете сделать столько проверок, сколько вам нужно. И проинформировать о проблемах так, как вам хочется. Но, если вы этого по каким-то причинам не сделали, то constrained_value не позволит вам вернуть заведомо некорректное значение. И тот, кто ждет от вас constrained_value, может быть в этом уверен.


Я, вообще-то, не хочу иметь в программе переменную, которая выглядит как целочисленная, только не позволяет складывать, при каждом присваивании делает пару проверок и иногда плюется исключениями. Это совершенно вредная штука, пусть даже C++ и позволяет создавать их с легкостью.

Pzz>>В C я написал бы явную проверку.


S>И после этого вы еще чего-то говорите про человеческий фактор и его влияние?


Говорю, да. В программе на C++, скорее всего, ничего, кроме проверки, встроенной в constrained_value, и не будет. И исключение никто не будет обрабатывать до самого верха. А наверху приделают кнопочку "ой, программа упала, послать дамп разработчикам?". Таков он, человеческий фактор.

S>Рискую вас удивить, но в C++ вы запросто можете вернуть, скажем expected, которое будет содержать либо нормальный результат, либо ошибку. Что сильно лучше, чем два значения в Go, одно из которых заведомо некорректно.


Угу. А потом мы начинаем сводить в одном проекте 5 библиотек, каждая из которых содержит свою реализацию expected, совершенно идентичную 4-м остальным, но формально несовместимую с ними, потому что разные типы.
Re[6]: А С++ то схлопывается...
От: nekocoder США  
Дата: 02.11.19 14:36
Оценка: +2
Здравствуйте, alex_public, Вы писали:

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


Хорошо вам там в альтернативной вселенной, где проекты сразу после завершения выбрасываются и переписываются с нуля.
Re[9]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 14:56
Оценка: +1
Здравствуйте, Pzz, Вы писали:

_>>Глупости какие. Я например периодически пишу код для МК и использую там на полную удобства C++17 (скоро уже на 20 буду переползать). При этом там естественно нет динамического выделения памяти в принципе.


Pzz>А что значит, нету в принципе? Ты не используешь слово new,


Все "выделения" памяти в проекте делятся на 3 части: глобальные переменные, статические переменные (по сути те же глобальные, только с ограниченной областью видимости), переменные на стеке. Динамической кучи нет в принципе, как явления (да и куда её там размещать в 16 Кб оперативки, в которых при этом ещё и стек должен помещаться?).

Pzz>или все твои алгоритмы имеют требования к памяти O(1)?


Скажем так: в данной области почти всегда алгоритмы подгоняют под железо, а не наоборот.
Re[20]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 15:01
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>В C я написал бы явную проверку. И вернул бы явную ошибку. А в Go еще удобнее, я вернул бы результат и ошибку одним махом, там функция может вернуть сразу несколько значений.


Ну это уже совсем незнание темы... В C++ давным давно можно было возвращать несколько значений с помощью кортежей. А в последнем стандарте ещё и добавили к этому максимальный сахар (https://en.cppreference.com/w/cpp/language/structured_binding), чтобы стало уж совсем удобно (как в Питоне и тому подобных языках).
Re[7]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 15:09
Оценка:
Здравствуйте, nekocoder, Вы писали:

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

N>Хорошо вам там в альтернативной вселенной, где проекты сразу после завершения выбрасываются и переписываются с нуля.

Ээээ, что? С чего бы это мой текущий проект (написанный на C++17) после своего релиза вдруг резко станет legacy? Ну т.е. конечно же лет через 10-15 (если проект просуществует всё это время) он возможно и станет таковым, но я им точно уже заниматься не буду (на самом деле я им уже и через год заниматься не буду, но это к делу не относится — будут заниматься сотрудники и для них он всё равно очевидно не будет legacy).
Re[21]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 15:21
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну это уже совсем незнание темы... В C++ давным давно можно было возвращать несколько значений с помощью кортежей. А в последнем стандарте ещё и добавили к этому максимальный сахар (https://en.cppreference.com/w/cpp/language/structured_binding), чтобы стало уж совсем удобно (как в Питоне и тому подобных языках).


Я знаю про тупли. Но тупли — это не то же самое, что возврат нескольких значений.
Re[22]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 02.11.19 15:23
Оценка:
Здравствуйте, Pzz, Вы писали:

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


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

Вы все это сможете увидеть в типах и компилятор с run-time будет бить вам по рукам за каждый шаг в сторону. Это сильно лучше, чем обычные int-ы или float-ы с комментариями вокруг них.

Pzz>Говорить об инструменте имеет смысл в контексте решения практических, а не школьных, задач.


Так вы же не можете в примеры. Ну вот совсем. Ваш максимум -- это сравнение с презервативами. Ничего предметного в обсуждении от вас не было. Ну, кроме демонстрации незнания C++.

Pzz>Если довести ваш пример до нормального состояния, что там был ваш constrained_value, что его не было, разница будет не шибко заметна.


Давайте сначала увидим ваш вариант этого constrained_value на чистом C. После чего можно будет, если будет возможность, поговорить и о том, чего вы в наличии и использовании constrained_value в упор не понимаете.

Pzz>Я, вообще-то, не хочу иметь в программе переменную, которая выглядит как целочисленная,


Так она и не выглядит как целочисленная. Она выглядит как жесткий контейнер для одного значения.

Pzz>Говорю, да. В программе на C++, скорее всего, ничего, кроме проверки, встроенной в constrained_value, и не будет. И исключение никто не будет обрабатывать до самого верха. А наверху приделают кнопочку "ой, программа упала, послать дамп разработчикам?". Таков он, человеческий фактор.


Давайте назовем вещи своими именами: в вашей программе на C++, скорее всего, ничего, кроме проверки, встроенной в constrained_value, и не будет. И исключение вы не будете обрабатывать до самого верха.

Так оно всяко объективнее получится.

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


Вообще-то не зря была дана ссылка на expected, поскольку это уже доступная сейчас реализация того, что будет в C++20.

Но даже такой зоопарк будет сильно лучше, чем обычный int в чистом C, который будет гулять между модулями вообще без какой-либо сопроводительной информации.
Re[10]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.11.19 15:26
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Скажем так: в данной области почти всегда алгоритмы подгоняют под железо, а не наоборот.


У меня был проектик, в котором памяти было 128 байт. Причем мне сначала наврали, что их 256, а я сдуру и не проверил. А потом стек сделал wrap around, и пришлось импровизировать на ходу
Re[22]: А С++ то схлопывается...
От: alex_public  
Дата: 02.11.19 15:55
Оценка:
Здравствуйте, Pzz, Вы писали:

_>>Ну это уже совсем незнание темы... В C++ давным давно можно было возвращать несколько значений с помощью кортежей. А в последнем стандарте ещё и добавили к этому максимальный сахар (https://en.cppreference.com/w/cpp/language/structured_binding), чтобы стало уж совсем удобно (как в Питоне и тому подобных языках).

Pzz>Я знаю про тупли. Но тупли — это не то же самое, что возврат нескольких значений.

Вообще то в большинстве языков оно как раз через кортежи и работает (например Питон):
>>> def test():       
...     return 2, 3
>>>a, b = test()            
>>> type(test())      
<class 'tuple'>


Да и в чём ты видишь принципиальную разницу между таким кодом (Go):
func test() (int, int) {
    return 2, 3
}
a, b := test()

и таким (C++):
tuple(int, int) test() {
    return {2, 3}
}
auto [a, b] = test();


a?
Re[17]: А С++ то схлопывается...
От: Denis Ivlev  
Дата: 02.11.19 17:28
Оценка: :)
Здравствуйте, Ночной Смотрящий, Вы писали:

DI>>7-8 будет хайлоад, я там выступаю с докладом


НС>Не нашел


У тебя в паспорте тоже не Ночной Смотрящий написано. Есть желание пересечься и пообщаться немного — пиши в личку, встретимся и пообщаемся
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.