LINUX.ORG.RU

Насильное ограничение подмножества C++ в проекте

 ,


0

6

Привет, ЛОР!

Скажи, а какие есть рецепты для сабжа? Допустим, я не хочу, чтобы в проекте использовались сырые указатели, new/delete, вызовы из cstdlib и прочие штуки, которым в современном C++ есть более кошерная замена. Есть ли возможность завалить сборку, если в коде такое встретилось? В идеале, я представляю себе некую утилиту, которая анализирует исходники и выдаёт предупреждение, если встретилось что-то из заданного ей списка.

Спасибо, ЛОР.

Ответ на: комментарий от rupert

Согласен. На самом деле то что другой товарищ выше назвал «паттерном» на полновесный паттерн не тянет, но это довольно широко известная «passkey idiom». Нужно не только для make_shared() / make_unique() - при любом in-place construction (читаем - container::emplace() в вариациях) - стандартное решение.

А по поводу make_unique() - если отбросить синтаксический сахар (чтобы типы явно каждый раз не выписывать и делать auto ptr = make_unique…) единственное реальное применение это exception safety: вот так foo(unique_ptr<A>(new A), unique_ptr<B>(new B)); может течь, а с make_unique() - уже не может. Мои 2 копейки.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 4)

Есть всякие сертифицированные тулы, которые используются для комерческой разработки в автомтиве итд. Они обычно очень дорогие. Например, LDRA Есть компиляторы в которые такие возможности встроены но обычно это касается С а не С++. У плюсов часто используют AUTOSAR C++14 Coding Guidelines

vromanov ★★★
()
Ответ на: комментарий от a1ba

C++ это в буквальном смысле increment and return old.

А Rust – это буквально ржавчина. Ичо?

От единственной буквы в названии языка уже никуда не убежишь.

Схера ли? Как минимум, C и C++ уже давно не совместимы: очень здоровая часть кода на C в плюсах тупо не скомпилится. Да и убежать более чем можно, если выпердолить на мороз кучу древнего говна.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

И потом, как ты скриптом проверишь использование сырых указателей, например?

По-моему, ты сильно загоняешься, не надо это проверять. А new/delete грепается в одну строку, аналогично и с сишным <c.*>.

kvpfs ★★
()
Ответ на: комментарий от hateyoufeel

очень здоровая часть кода на C в плюсах тупо не скомпилится

Ой. Деды как писали clazz вместо class лишь бы с плюсовыми компиляторами работало, так и пишут и у них оно наверняка даже работает. Хотя к счастью рядом с плюсовым компилятор обычно есть и компилятор сишки, так что не так уж и актуально. :)

Да и убежать более чем можно

Разве что создать видимость до определенного момента, например первой библиотеки написанной на Си, работы с сисколлами ОС или первого интеропа с другими языками. Тут даже Rust не может избавиться от Си.

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

a1ba ★★
()
Последнее исправление: a1ba (всего исправлений: 2)
Ответ на: комментарий от alex1101

Компилятор понимает контекст. Но если бы мне очень хотелось вырезать сырые указатели, то вместо перегруженного разыменования, умножения и ещё парочки сделал бы макросы MULL DEREF(). И грепал бы в дальнейшем * ->

Но лично я в этом смысла не вижу, из действительно нужного - c cast’ты - компилятор и так показывает, reinterpret_cast - легко ищется. По поводу new/delete - согласен, в высокоуровнем коде им не место, тоже грепается без проблем.

kvpfs ★★
()

banned.h

#ifndef BANNED_H
#define BANNED_H

#define BANNED(func) alarm_##func##_usage_forbidden

#undef strcpy
#define strcpy(x,y) BANNED(strcpy)

#endif /* BANNED_H */

example.c

#include<stdio.h> 
#include<string.h> 
#include"banned.h" 

int main () 
{ 
    char str1[]="opengenus"; 
    char str2[] = "some data"; 
    
    strcpy(str2, str1); 
    printf ("str1: %s\nstr2: %s\n", str1, str2); 
    return 0; 
} 

примерно так

olelookoe ★★★
()
Ответ на: комментарий от a1ba

Деды как писали clazz вместо class лишь бы с плюсовыми компиляторами работало, так и пишут и у них оно наверняка даже работает.

Дядя, ты баклажан? Какие в жопу деды? Современный C и современный C++ давно разошлись путями, и код на современном C может включать фичи, которых в C++ нет. Например, вот эту: Зачем в C _Generic?

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Да кому этот _Generic нужен? Ему нормально только в tgmath.h, и тот нужен чтобы обернуть существующий код, нежели чем писать новый.

a1ba ★★
()
Последнее исправление: a1ba (всего исправлений: 1)
Ответ на: комментарий от a1ba

Да кому этот _Generic нужен?

Как видишь с том треде, кому-то да нужен.

Но ладно, вот тебе интереснее штука: в стандартном C++ нету flexible array в структурах. Т.е. ты не можешь написать вот такое:

struct s {
  int type;
  char array[];
};
hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Я как-то видел в одном проприетарном проекте, где под ifdef cplusplus отсутствие flexible array обошли через древний костыль с массивом размером в 1 элемент Скорее всего это дописал тот кому нужно было портировать код сишный в плюсы, лишь бы компилировалось.

Я к тому, что если захотят – выкрутятся. Даже если это будет стоить UB и статуса ССЗБ.

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

a1ba ★★
()
Последнее исправление: a1ba (всего исправлений: 2)
Ответ на: комментарий от a1ba

Я к тому, что если захотят – выкрутятся. Даже если это будет стоить UB и статуса ССЗБ.

UB – это ошибочный код. За его написание нужно давать в рожу.

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

ВАУ!!! Шанс встретить говнокод, написанный кретинами, больше нуля! Да ты пророк, мать твою за ногу!

Но я всё ещё не понимаю, что ты тут мне рассказать пытаешься. Что на C++ можно писать говно в стиле C? Ну, да, такая возможность существует. Что надо этим пользоваться и во всю обмазываться? Нет, так делать не надо, это плохо и за это тебя побьют.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

нужно давать в рожу

за это тебя побьют

Нам нужен турнир по боксу среди программистов. Отстоять свой говнокод за право быть замерженным!

Что надо этим пользоваться?

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

a1ba ★★
()

а, еще ж про операторы

#include <iostream>

using namespace std;

void* operator new (size_t size, const char* filename, int line) {
    void* ptr = new char[size];
    cout << "size = " << size << " filename = " << filename << " line = " << line << endl;
    static_assert (false , "oh, no, you did it again!" );
    return ptr;
}

#define new new(__FILE__, __LINE__)

int main() {
    int* x = new int;
}
olelookoe ★★★
()
Последнее исправление: olelookoe (всего исправлений: 1)
Ответ на: комментарий от a1ba

Скорее удивляться. Рано или поздно настигнет, выхода нет, всё тлен.

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

hateyoufeel ★★★★★
() автор топика

Судя по описанию, тебе нужно смотреть в сторону C++ Core Guidelines и тулзов, которые умеют проверять. Труп страуса такое лет десять назад обещал, в рамках программы «мы ничем не хуже раста», майкрософт обещали тулзу для проверки выпустить

khrundel ★★★★
()
Ответ на: комментарий от hateyoufeel

Списка нет, разве что могу посоветовать поискать ту самую тулзу от майков. Мой поинт в том, что ты пытаешься изобрести велосипед в то время как лучшие люди города уже запилили стандартное решение. Возможно, если clang-tidy пропускает что-то, что ты хотел бы запретить, то это потому, что запрещать такую фичу нельзя.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

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

Где? Я его не вижу.

Возможно, если clang-tidy пропускает что-то, что ты хотел бы запретить, то это потому, что запрещать такую фичу нельзя.

Ты это сам придумал? Почему нельзя? Без сырых указателей мой код на C++ превратится в тыкву?

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Где? Я его не вижу.

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

Ты это сам придумал?

Тебе завидно, что кто-то мог что-то «сам придумать»?

Почему нельзя? Без сырых указателей мой код на C++ превратится в тыкву?

Ну вообще да, превратится. Но даже давай возьмём чисто юзерский код, вынесем за скобки реализации того же stl или других библиотек, которые внутри обмазаны указателями со всех сторон. Как ты собрался передать необязательный параметр по ссылке в функцию? Без сырых указателей единственный простой вариант - это shared_ptr. Ну т.е. если руководитель проекта - самодур, то можно изгалиться, заменить все функции с необязательными параметрами на перегрузки, или паковать параметры полиморфные объекты, или ещё как, но в общем ни один плюсовик в таком проекте жить не захочет. Да и не решит это никаких проблем, там где ты избавишься от указателей, возникнет проблема сохранения висящих итераторов или даже тупо ссылок, тем более при запрете указателей кто-то обязательно выкрутится передав и сохранив ссылку. Поэтому если всерьёз хочешь безопасных плюсов - пользуйся вменяемым механизмом.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Найти несложно, учитывая что я 2 коротких сообщения в этой теме написал.

Покажи класс! В смысле, ссылку.

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

Ты читать не умеешь? У тебя хлебушек вместо мозга? Я хочу проверять МОЙ код, не STL или другие библиотеки.

Как ты собрался передать необязательный параметр по ссылке в функцию?

std::optional

Без сырых указателей единственный простой вариант - это shared_ptr.

Нет, потому что есть std::optional. Среди кучи прочих вариантов, на самом деле.

Да и не решит это никаких проблем

А я говорю, что решит. Чьё мнение более актуально для меня: того, что знает про std::optional, или того, у кого никнейм хрюндель?

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 3)
Ответ на: комментарий от hateyoufeel

Как ты собрался передать необязательный параметр по ссылке в функцию?

std::optional

Несмотря на то что так работать будет, основное предназначение optional - другое. И naked ptr в качестве необязательного параметра таки дешевле.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Несмотря на то что так работать будет, основное предназначение optional - другое.

Какое? Там указатель и флаг внутри. Не вижу проблемы передавать параметром, даже без ссылки.

И naked ptr в качестве необязательного параметра таки дешевле.

В 99% случаев вообще насрать. В оставшемся 1% можно прагму комментом сунуть.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Какое?

RAII без лишних mallocs. Например туда mutex lock класть удобно.

Там указатель и флаг внутри.

Всё правильно.

Не вижу проблемы передавать параметром

«Проблем» нет, а вот overhead по сравнению с naked ptr - очевиден.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

RAII без лишних mallocs. Например туда mutex lock класть удобно.

Не уверен, что это основное.

«Проблем» нет, а вот overhead по сравнению с naked ptr - очевиден.

Ага. И, как я уже написал, на него абсолютно посрать. Это экономия на спичках, которая почти никогда не оправдана. Большая часть тормозов в софте случается совсем не потому что кто-то где-то лишний bool сунул.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Не уверен, что это основное.

99% моих использований optional - именно такие. Готов предположить - у многих по-другому.

Большая часть тормозов в софте случается совсем не потому что кто-то где-то лишний bool сунул.

Не в бровь, а в глаз. Но в терминах overhead - там чуть больше чем «лишний» байтик на стеке.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Там указатель и флаг внутри.

Всё правильно.

Возьму свои слова обратно - там объект и bool. Указателя нет. Заменяет unique_ptr, но без лишних mallocs.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Покажи класс! В смысле, ссылку.

Я обычно убогим не подаю, но так и быть, сегодня сделаю исключение: Насильное ограничение подмножества C++ в проекте (комментарий)

Ты читать не умеешь? У тебя хлебушек вместо мозга? Я хочу проверять МОЙ код, не STL или другие библиотеки.

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

std::optional

Ок, принимается. Хотя стоит ли связываться с плюсами если тупо не можешь передать NULL в функцию.

А я говорю, что решит.

Потому что ты тупой. Я тебе выше предложил 2 проблемы, но ты их проигнорировал, походу даже не понял что с ними не так.

Чьё мнение более актуально для меня: того, что знает про std::optional, или того, у кого никнейм хрюндель?

Ты пришёл сюда просить Хрюнделя, чтоб тот поделился с тобой своей мудростью. Будь благодарен, а не хами в ответ. Впрочем, если ты собрался меряться пиписьками то я советую тебе обращаться к Страуструпу, именно он публично благославлял эти самые core guidelin’ы. Ты не первый, кто решил сделать безопасные плюсы. Из одной из таких попыток впоследствии родился Раст, из другой - эти самые гайдлайны. Люди, гораздо более погружённые в тему, чем ты, пришли к выводу что простого решения не существует. Но они мало что понимают, дурачок с лорчика знает лучше, ему только тулзу, которая указатели отловит, подскажите, плз.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Я обычно убогим не подаю, но так и быть, сегодня сделаю исключение: Насильное ограничение подмножества C++ в проекте (комментарий)

сходил по ссылке, утилиты не увидел. Зочем ты меня обманываешь?

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

Ты меня раскусил! И начну я с тебя. Приду к тебе домой и буду проверять твой код, пока ты кровоточить не начнёшь. Такова твоя незавидная участь.

Хотя стоит ли связываться с плюсами если тупо не можешь передать NULL в функцию.

Почему нет? NULL не нужен, если не считать какого-нибудь совсем низкоуровнегого говна или реализации этих ваших *_ptr. Указатель должен либо указывать на существующий объект, либо сам не должен существовать.

Из одной из таких попыток впоследствии родился Раст

Руст родился из попытки натянуть на OCaml полуручное управление памятью, без GC. От C++ там только всратый синтаксис.

Блин, у тебя потрясающе жопу рвёт. Я пожалуй буду тебя в треды по плюсам кастовать почаще!

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 3)
Ответ на: комментарий от hateyoufeel

сходил по ссылке, утилиты не увидел. Зочем ты меня обманываешь?

Какой утилиты, болезный? Краткое содержание предыдущих серий:

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

Где? Я его не вижу.

Стандартное решение - это не искать утилиту, которая запретит фичи которые тебе кажутся опасными, а взять тот самый «безопасный c++», который тебе Страуструп предлагает.

Ты меня раскусил! И начну я с тебя. Приду к тебе домой и буду проверять твой код,

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

Почему нет? NULL не нужен, если не считать какого-нибудь совсем низкоуровнегого говна или реализации этих ваших *_ptr.

Не нужен, конечно, но так уж повелось в плюсах, что он везде и вполне идиоматичен для этого языка. Это как со строками, можешь пользоваться любой реализацией, но рано или поздно придётся вызвать c_str(). Так и тут, половина кода при общении с библиотеками будет проверять на null, половина на end() ну и ещё optional от тебя добавится.

Руст родился из попытки натянуть на OCaml полуручное управление памятью, без GC.

Мда… Я полагал, что такие вещи как что стоит левее, имя переменной или её тип - это второстепенно, а оказывается наоборот, самое главное синтаксис. Впрочем, твой уровень.

Блин, у тебя потрясающе жопу рвёт. Я пожалуй буду тебя в треды по плюсам кастовать почаще!

А месье-то оказывается тонкий психолог. Сначала объявил о полной капитуляции оппонента, а потом ловко применил реверсивную психологию, типа я сейчас сделаю наоборот и свалю. Ты победил, я свалю. Я вообще думал, что человек просто чего-то не знает и просит хрень вместо того чтоб сделать по-человечески. Ты же утверждаешь, что ты всё знаешь, но просишь вместо этого хрень осознанно. Ну ок, хозяин - барин.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Ты пришёл сюда просить Хрюнделя, чтоб тот поделился с тобой своей мудростью.

А получил очередной копинг от контуженных программистов на C. Вам уже и std::optional дали, и умные указатели, и раст принесли, а вы все свои указатели пихаете, которые то NULL где не надо, то use-after-free.

cumvillain
()
Ответ на: комментарий от cumvillain

я не контуженный программист на си, я вообще всерьёз ничего на плюсах не писал года с 2005го, потом всё больше что-то уровня хелловорлда. Однако даже я понимаю, что если ты готов вот просто так взять и уехать в Урюпинск, то тебе как бы плюсы и не нужны, бери хипсторский Раст и живи себе счастливо. А вот для тех, кто хочет и безопасно и на плюсах (и на C соответственно) придумали кор гайдлайнс. Я не сильно верю в эту инициативу, по мне это такой «ответ чемберлену», на фоне хайпа по поводу раста выкатили «а мы тоже можем свой раст запилить», но это моё мнение, основанное в общем-то ни на чём. Я доверяю авторам, они говорят, что смогли обеспечить и безопасность, и относительную совместимость с C и плюсами, ну как бы хорошо, молодцы. Вопрос только в том, примут ли плюсовики это или предпочтут стрелять в направлении ноги.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Какой утилиты, болезный?

Пролистай в самый верх и прочитай оригинальный пост:

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

Ты мне предложил почитать CPP Core Guidelines. Но читать я их умею, а вот проверять код на соответствие сам не очень хочу.

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

Ты опять с голосами в своей голове тут общаешься? Перечитай по буквам: семантика языка в Rust почти целиком списана с OCaml и немного с Haskell (трейты).

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от cumvillain

Меня куда больше интересует причем тут Урюпинск.

Выросло поколение, не знающее анекдот про уехать в Урюпинск.

Хорошо, разжую метафору: Урюпинск - это город, в котором не знают некую сложную тему, в которой автор высказывания разбирается. И он поэтому мечтает «бросить всё и уехать в Урюпинск». Применимо к плюсам, отказ от совместимости с C, от прямого вызова сишных функций и библиотек - это в общем-то можно сравнить с «бросить всё».

khrundel ★★★★
()
Ответ на: комментарий от hateyoufeel

Пролистай в самый верх и прочитай оригинальный пост:

Прочитай мой ответ, клован.

Ты мне предложил почитать CPP Core Guidelines. Но читать я их умею, а вот проверять код на соответствие сам не очень хочу.

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

Ты опять с голосами в своей голове тут общаешься? Перечитай по буквам: семантика языка в Rust почти целиком списана с OCaml и немного с Haskell (трейты).

Тебе явно следует выяснить, что такое семантика. Иначе никак не объяснить, как ты умудрился Haskell в родители расту записать. После этого ты, может, и поймёшь, что «натянуть полуручное управление памятью» - это важнее чем то, с какой стороны от переменной стоит её тип.

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

khrundel ★★★★
()
Ответ на: комментарий от hateyoufeel

Мне что-то кажется, что Хрюндель бухой в говнину. Причём уже не первый день, похоже.

Вот это лишнее, месье психолог. Так ведь кто-то может подумать, что это не у меня жопу рвёт, а совсем даже и наоборот.

khrundel ★★★★
()
Ответ на: комментарий от bugfixer

Твою мать, а к чему тогда:

«В огороде бузина, а в Киеве дядька». Как отсутствие близкого контакта с плюсами связана с мнением, что дурачок с лорчика разбирается в плюсах хуже их автора?

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Как отсутствие близкого контакта с плюсами

Гхм. У меня лет 10 плотненького девелопмента в пром масштабах ушло чтобы действительно начать понимать что к чему. И, спешу заметить - я всё ещё продолжаю учиться. А ваши познания почти 20 летней давности и без практического опыта, ну вы поняли - вы сами знаете что с ними сделать и куда их засунуть.

связана с мнением, что дурачок с лорчика разбирается в плюсах хуже их автора?

Эвона как.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Гхм. У меня лет 10 плотненького девелопмента в пром масштабах ушло чтобы действительно начать понимать что к чему. И, спешу заметить - я всё ещё продолжаю учиться. А ваши познания почти 20 летней давности и без практического опыта, ну вы поняли - вы сами знаете что с ними сделать и куда их засунуть.

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

Эвона как.

Знаешь, что самое смешное? Если я сейчас восприму твои слова всерьёз, как утверждение «Страуструп понимает проблемы безопасных плюсов не лучше юзера hateyoufeel» ты тут же заявишь, что ничего подобного не говорил. И это будет правдой, ты ведь не говорил, а просто пукнул в лужу.

khrundel ★★★★
()
Последнее исправление: khrundel (всего исправлений: 1)