Доки дивився відос про модулі в C++, на які я чекав з часів C++0x (спойлер: все сплюндровано — чи то досі, чи зовсім 🤷🏻♂️ ), згадав про таку білд-систему як xmake, що походить, вірогідно, з Китаю. Вона базується на #Lua, як і Premake, але якось вже розвинутіше виглядає. За ті два роки, котрі я її ігнорував, вони додали підтримку купи мов на кшталт #Zig, #Nim або #Rust і навіть зробили свій пекедж-менеджер. Плюс Lua сама по собі доволі проста та приємна — точно краща за CMake. Може колись нарешті знайду щось, що задовольнить мене хоча б на рівні #Qbs, щоб нарешті від нього відмовитися.
YouTube
So, you want to use C++ Modules ...cross platform - Daniela Engert - Meeting C++ 2023
So, you want to use C++ Modules ...cross platform - Daniela Engert - Meeting C++ 2023
Slides: https://slides.meetingcpp.com
Survey: https://survey.meetingcpp.com
If you are interested in the topic of C++ Modules you are probably aware of the fact that the…
Slides: https://slides.meetingcpp.com
Survey: https://survey.meetingcpp.com
If you are interested in the topic of C++ Modules you are probably aware of the fact that the…
👀1
Я інколи кажу, що C++ — це хороша мова з поганими дефолтами. Маю на увазі, що мова дуже потужна і дозволяє робити купу всього, але програміста при цьому примушує тримати купу деталей в голові, щоб не схибити десь.
Нюанс полягає в тому, що мови з хорошими дефолтами я поки не бачив, хоч деякі з них намагаються виправити бодай якусь маленьку проблему, що вже непогано. Як в тому ж #Rust зробили, щоб всі «змінні» стандартно були константами. Воно ж і логічно, ні? Як часто вам насправді треба мати мутабельні змінні? З поточними практиками — дуже рідко, бо через вплив ФП ви найімовірніше просто позначаєте якесь проміжне immutable значення окремим імʼям. Але в C++ для оголошення константи програмісти мусять окрему роботу виконати — написати
Або додали ось в C++11 атрибути, зокрема🤯 «Навіщо?» — спитаєте ви. Я теж не одразу второпав.
Є у вас, наприклад, так званий mutex guard — така штука, яка локає мьютекс при створенні та автоматом анлокає його при виході зі скоупу (при знищенні). Як
Річ у тім, що можна хибно написати ось такий код, і компілятор вам жодного слова не скаже:
Короч, як ви вже здогадалися, щоб уникнути останньої проблеми, можна позначити конструктор як
Логічно? «Логічно»!😅 Але чому це не стандартна поведінка? Ніхто того не зна. Як часто ви пишете функції, які повертають значення, яке можна ігнорувати? Нащо тоді вони його повертають? А як часто ви пишете класи, екземпляри яких ніяк не використовуються? Чисто заради сайд-ефектів чи що?
У #Nim теж так подумали й зробили всі значення non-discardable, причому компілятор одразу помилку пише, а не попередження:
І щоб виправити це, треба буквально сказати йому, що значення вам не потрібне:
Круто, еге ж?
Вирішив пошукати, в яких ще імперативних мовах таке є, і виявилося, що в жодній! #Zig та #Swift нібито попередження видають, але це не точно. А ще в #Rust є схожий пропоузал. Чому ніхто цього не робить? Є ідеї? )
Нюанс полягає в тому, що мови з хорошими дефолтами я поки не бачив, хоч деякі з них намагаються виправити бодай якусь маленьку проблему, що вже непогано. Як в тому ж #Rust зробили, щоб всі «змінні» стандартно були константами. Воно ж і логічно, ні? Як часто вам насправді треба мати мутабельні змінні? З поточними практиками — дуже рідко, бо через вплив ФП ви найімовірніше просто позначаєте якесь проміжне immutable значення окремим імʼям. Але в C++ для оголошення константи програмісти мусять окрему роботу виконати — написати
const
. Легко забути та скіпнути? Легко.Або додали ось в C++11 атрибути, зокрема
[[nodiscard]]
в C++17. Якщо функцію таким позначити, то компілятор «заохочується» 😆 видати попередження, що треба щось зробити зі значенням, що повертається. І як виявилося, подібним атрибутом можна позначити конструктор Є у вас, наприклад, так званий mutex guard — така штука, яка локає мьютекс при створенні та автоматом анлокає його при виході зі скоупу (при знищенні). Як
std::lock_guard
, ага. Використовується наступним чином:{
const mega_guard lock{mutex};
// ...
}
Річ у тім, що можна хибно написати ось такий код, і компілятор вам жодного слова не скаже:
{
mega_guard{mutex}; // не lvalue, тож одразу знищується, звільняючи мьютекс
// ...
}
Короч, як ви вже здогадалися, щоб уникнути останньої проблеми, можна позначити конструктор як
[[nodiscard]]
:class mega_guard {
public:
[[nodiscard]] explicit mega_guard(mutex &);
// ...
};
Логічно? «Логічно»!
У #Nim теж так подумали й зробили всі значення non-discardable, причому компілятор одразу помилку пише, а не попередження:
proc sum(x, y: int): int =
result = x + y
sum(3, 4) # Error: expression 'sum(3, 4)' is of type 'int' and has to be discarded
І щоб виправити це, треба буквально сказати йому, що значення вам не потрібне:
discard sum(3, 4)
Круто, еге ж?
Вирішив пошукати, в яких ще імперативних мовах таке є, і виявилося, що в жодній! #Zig та #Swift нібито попередження видають, але це не точно. А ще в #Rust є схожий пропоузал. Чому ніхто цього не робить? Є ідеї? )
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2
Я усвідомлюю, що мені просто впадлу вчити #Rust, тож я й не вчу, але все одно лишалося це відчуття, що може весь хайп не з порожнього місця і що може варто було б звернути увагу.
Друган в коментарях до іншого допису вже наводив приклади, і ось зараз рєпа cve-rs нарешті закрила для мене це питання остаточно. Memory safety — це брехня, розходимося😂
Друган в коментарях до іншого допису вже наводив приклади, і ось зараз рєпа cve-rs нарешті закрила для мене це питання остаточно. Memory safety — це брехня, розходимося
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6😱3👍1🤡1
Після вчорашніх всесвітніх забавок через CrowdStrike це було питанням часу, коли знов почнуть парити про memory safety звідусіль.
І справді, наразі найбільш помітні та водночас підозрілі факти — це забитий нулями sys-файл драйвера та спроба звернутися до памʼяті через null-вказівник. Про друге я додам від себе «пару» слів.
Навіть якщо тред не дочитали, у вас, мабуть, все одно промайнула думка, мовляв, треба було на #Rust писати — там-то таке не могло трапитися, бо «Rust же — МЕМОРІ-СЕЙФ!!!11», не те що ваш C++.
Теза перша:
Це далеко не єдиний вид безпеки, який треба забезпечити, і маючи тільки його ви досі маєте нуль гарантій, що ваша програма коректна🙁 , бо купа іншого може наламатися. Я вже скидав сюди відос Страуструпа на тему. З іншого боку, звісно, добре мати на одну проблему менше, але треба б ще бути певним, що воно не додає інших.
Теза друга:
І вони в жодному разі одна одну не виключають. В універах навіть змушують здавати охорону праці, яку ви, певен, ненавиділи, для отримання диплома. Вгадайте навіщо.
У моєму дитинстві у нас в хаті були спеціальні пластикові заглушки в розетках «від/для дітей». І знаєте що? Це не спинило малого мене перевірити, що буде, якщо встромити в розетку довгогубці, які так чудово пасували під два отвори. Інструмент (заглушки) був, а дисципліни бракувало.
Теза третя:
Подумайте самі. У вас вдома праска є? Чи безпечний це інструмент? Ну, з розвитком технологій стало краще звісно, та трирічному мені, який вхопився долонею за розпечену поверхню, так не здавалося. Навіть якщо прибрати аспект високої температури, праска може на ногу впасти чи на голову з шафи, чи… ну, я не знаю… у ванну вам, підʼєднана до розетки при цьому. Як ми уникаємо цього? Дисципліною під час використання звісно. А дисципліна потребує навчання, потребує формування навичок — потребує часу, іншими словами.
Або ножі… Ух, це просто протилежність слова «безпечний», і все ж в кожній хаті є щонайменше декілька. Навіть якщо у вас є безпечніша нарізна машина (блендер якийсь абощо), то й звичайні ножі все одно також.
Або варильні поверхні. Ось тут прям прогрес помітний. В дитинстві у більшості газові були. Та й досі є, але я вже років 10 не користувався. Є резистивні електричні. Вони не тільки безпечніші, бо немає відкритого полумʼя або можливості лишити відкритим газ, так у них і ККД більше. А ще є індукційні, які на жаль потребують особливого посуду, але натомість отримуємо миттєвий нагрів, ККД на рівні 90%, неможливість ввімкнути порожню тощо. При цьому місця займає стільки ж, перенавчатися для користування не треба. Оце я розумію — покращення!
Повертаючись до null-поїнтерів… Я великий шанувальник кращих інструментів. Коли я бачу щось, що будь-яким чином покращує мені роботу чи життя — я, не вагаючись, починаю цим користуватися.
Та не буває нічого безпечного на 100%. Всі інструменти небезпечні до певної міри. Просто вчіться, бляха, ними користуватися!
У сучасному C++ писати raw-вказівники взагалі вважається ганьбою, тому що вже існує купа засобів та методів програмувати цією мовою на порядок безпечніше.
І Rust міг би бути інструментом, що ще більше поліпшує життя програмістам, та я не бачу, щоб він ним справді був. Конкретно в цій ситуації з null-поїнтером Rust може й справді б зарадив, але в численних інших — ні, а у деяких випадках може й інші проблеми б приніс. Та в будь-яких розмовах на цю тему мова C++ — це завжди щось чорне-чорне, суцільне зло, винахід диявола, небезпека небезпек, а Rust — це завжди порятунок, манна небесна, silver bullet та ложка з «Матриці». Ні! Заїбало.
Звинуватити C++ легко. Але скажіть мені краще, як так вийшло, що 45-кілобайтний sys-файл був забитий нулями, і це потрапило в реліз. Де дисципліна, Лебовскі?
І справді, наразі найбільш помітні та водночас підозрілі факти — це забитий нулями sys-файл драйвера та спроба звернутися до памʼяті через null-вказівник. Про друге я додам від себе «пару» слів.
Навіть якщо тред не дочитали, у вас, мабуть, все одно промайнула думка, мовляв, треба було на #Rust писати — там-то таке не могло трапитися, бо «Rust же — МЕМОРІ-СЕЙФ!!!11», не те що ваш C++.
Теза перша:
Безпека доступу до памʼяті — не єдине, про що треба подбати.
Це далеко не єдиний вид безпеки, який треба забезпечити, і маючи тільки його ви досі маєте нуль гарантій, що ваша програма коректна
Теза друга:
На мій погляд, безпека може забезпечуватися щонайменше двома різними методами: безпекою інструментів та дисциплінарною безпекою.
І вони в жодному разі одна одну не виключають. В універах навіть змушують здавати охорону праці, яку ви, певен, ненавиділи, для отримання диплома. Вгадайте навіщо.
У моєму дитинстві у нас в хаті були спеціальні пластикові заглушки в розетках «від/для дітей». І знаєте що? Це не спинило малого мене перевірити, що буде, якщо встромити в розетку довгогубці, які так чудово пасували під два отвори. Інструмент (заглушки) був, а дисципліни бракувало.
Теза третя:
Найкращий інструмент — не той, що є найбезпечнішим, та не той, що дає результат найшвидше, а той, що забезпечує найкращий баланс цих двох параметрів під конкретну задачу.
Подумайте самі. У вас вдома праска є? Чи безпечний це інструмент? Ну, з розвитком технологій стало краще звісно, та трирічному мені, який вхопився долонею за розпечену поверхню, так не здавалося. Навіть якщо прибрати аспект високої температури, праска може на ногу впасти чи на голову з шафи, чи… ну, я не знаю… у ванну вам, підʼєднана до розетки при цьому. Як ми уникаємо цього? Дисципліною під час використання звісно. А дисципліна потребує навчання, потребує формування навичок — потребує часу, іншими словами.
Або ножі… Ух, це просто протилежність слова «безпечний», і все ж в кожній хаті є щонайменше декілька. Навіть якщо у вас є безпечніша нарізна машина (блендер якийсь абощо), то й звичайні ножі все одно також.
Або варильні поверхні. Ось тут прям прогрес помітний. В дитинстві у більшості газові були. Та й досі є, але я вже років 10 не користувався. Є резистивні електричні. Вони не тільки безпечніші, бо немає відкритого полумʼя або можливості лишити відкритим газ, так у них і ККД більше. А ще є індукційні, які на жаль потребують особливого посуду, але натомість отримуємо миттєвий нагрів, ККД на рівні 90%, неможливість ввімкнути порожню тощо. При цьому місця займає стільки ж, перенавчатися для користування не треба. Оце я розумію — покращення!
Повертаючись до null-поїнтерів… Я великий шанувальник кращих інструментів. Коли я бачу щось, що будь-яким чином покращує мені роботу чи життя — я, не вагаючись, починаю цим користуватися.
Та не буває нічого безпечного на 100%. Всі інструменти небезпечні до певної міри. Просто вчіться, бляха, ними користуватися!
У сучасному C++ писати raw-вказівники взагалі вважається ганьбою, тому що вже існує купа засобів та методів програмувати цією мовою на порядок безпечніше.
І Rust міг би бути інструментом, що ще більше поліпшує життя програмістам, та я не бачу, щоб він ним справді був. Конкретно в цій ситуації з null-поїнтером Rust може й справді б зарадив, але в численних інших — ні, а у деяких випадках може й інші проблеми б приніс. Та в будь-яких розмовах на цю тему мова C++ — це завжди щось чорне-чорне, суцільне зло, винахід диявола, небезпека небезпек, а Rust — це завжди порятунок, манна небесна, silver bullet та ложка з «Матриці». Ні! Заїбало.
Звинуватити C++ легко. Але скажіть мені краще, як так вийшло, що 45-кілобайтний sys-файл був забитий нулями, і це потрапило в реліз. Де дисципліна, Лебовскі?
Please open Telegram to view this post
VIEW IN TELEGRAM
😁10👍6😱1