CPPLASTIC Telegram 194
Я інколи кажу, що C++ — це хороша мова з поганими дефолтами. Маю на увазі, що мова дуже потужна і дозволяє робити купу всього, але програміста при цьому примушує тримати купу деталей в голові, щоб не схибити десь.

Нюанс полягає в тому, що мови з хорошими дефолтами я поки не бачив, хоч деякі з них намагаються виправити бодай якусь маленьку проблему, що вже непогано. Як в тому ж #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
👍42



tgoop.com/cpplastic/194
Create:
Last Update:

Я інколи кажу, що C++ — це хороша мова з поганими дефолтами. Маю на увазі, що мова дуже потужна і дозволяє робити купу всього, але програміста при цьому примушує тримати купу деталей в голові, щоб не схибити десь.

Нюанс полягає в тому, що мови з хорошими дефолтами я поки не бачив, хоч деякі з них намагаються виправити бодай якусь маленьку проблему, що вже непогано. Як в тому ж #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 є схожий пропоузал. Чому ніхто цього не робить? Є ідеї? )

BY Cіпласпластик


Share with your friend now:
tgoop.com/cpplastic/194

View MORE
Open in Telegram


Telegram News

Date: |

It’s easy to create a Telegram channel via desktop app or mobile app (for Android and iOS): The public channel had more than 109,000 subscribers, Judge Hui said. Ng had the power to remove or amend the messages in the channel, but he “allowed them to exist.” Public channels are public to the internet, regardless of whether or not they are subscribed. A public channel is displayed in search results and has a short address (link). SUCK Channel Telegram Informative
from us


Telegram Cіпласпластик
FROM American