LINUX.ORG.RU

Использовать ли голые указатели, new, delete и т.п. в новом проекте или сразу начинать с стандарта 11+?

 


0

6

Использовать ли голые указатели, new, delete и т.п. в новом проекте или сразу начинать с стандарта 11+?

Перемещено hobbit из general

Ответ на: комментарий от ya-betmen

Поведение функции аналогично lfind(3). Если аргумент since не указан (NULL), то берется начало массива. Если finish не указан (NULL), то берется конец массива. Функция возвращает указатель на первый найденный элемент или NULL.

Что тут непонятного?

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

Это просто чтобы показать какую херню придумали в ISO.

final должен быть атрибутом. Они же придумали зачем-то «особый идентификатор» вместо этого.

И да, синтаксис атрибутов в C++11 тоже ужасный. Зачем добавлять [[такие]] атрибуты, когда все используют __attribute__ (такие) атрибуты. Атрибуты в нормальном коде не пишутся, они пишутся только в узких, компиляторозависимых местах. Следовательно [[этот]] уродливый синтаксис просто не имеет смысла, потому что в обычном коде его не будет, а в супер оптимизированном будут атрибуты от компилятора.

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

в чем плюс от использование std::make_unique?

foo(make_unique<T>(), make_unique<U>()); // exception safe

foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe

До C++17 последовательность вычислений параметров могла быть любой. Компилятор мог сначала вычислить new T и new U, а уже потом их результаты передавать в unique_ptr<>. В результате если второй new бросит исключение, память от первого утекает, потому что указатель ещё не был обёрнут в unique_ptr<>. Начиная с C++17 стандарт накладывает ограничения на последовательность вычислений, и второе выражение становится безопасным в плане обработки исключений.

i-rinat ★★★★★
()
Ответ на: комментарий от zx_gamer

Следовательно [[этот]] уродливый синтаксис просто не имеет смысла, потому что в обычном коде его не будет

Довольно много видел [[nodiscard]] и [[fallthrough]]. Их используют в обычном коде, по очевидным причинам.

Это просто чтобы показать какую херню придумали в ISO.

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

i-rinat ★★★★★
()
Ответ на: комментарий от James_Holden
auto p = std::make_shared<CoolClass>();

Только вот с 17го стандарта этот соломенный самолет не нужен для того для чего его по-быстренькому вытесали из палок и склеили говном изначально. Особенно если shared не используются. Но на собесах, разумеется, умничают про него, не уточняя какой стандарт имеют в виду. А в коде у них и подавно С++98 с аж тремя велосипедными реализациями «умного» autoptr: autoptr2, autoptr3, каждая из которых каличная по-своему.

slackwarrior ★★★★★
()
Ответ на: комментарий от ya-betmen

Потому что указатель удобнее итератора. Указатель может неявно быть проверен на NULL. Указатель поддерживается самим языком, поэтому нет нужны в разных классах: iterator и const_iterator. Указатель может быть NULL, поэтому не нужны костыли с «элемент после последнего» и втекающими костылями с std::next и подобными обертками. Использование итераторов замедляет компиляцию, потому что это шаблонная мазня на ровном месте.

Итератор выглядит как бесполезный слой абстракции.

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

А смысл? new T(args) явно короче, чем std::make_unique<T>(args), а смысла несет ровно столько же.

это изначально был костыль кривой риализации, потом перешло в разряд «традиции», у которой разумеется, немедленно появились «истинные адепты», большинству из которых соственно код писать не приходится — например, какая им эксепшонсейфти приснилась в кодовой базе, где эксепшоны табу и STL не используется тоже. (Лично я желаю обеим командам успеха... или хотя бы получить удовольствие.)

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

Довольно много видел [[nodiscard]] и [[fallthrough]]. Их используют в обычном коде, по очевидным причинам.

Ни разу не видел. Зато часто видел, когда API требует написать функцию, которая принимает какие-то параметры, то чтобы компилятор не кидал варинги на неиспользуемые пишу-то что-то такое:

void f(A a, B b, C c) { (void)a; (void)b; (void)c; }

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

Что-то мне кажется, они не оценят, если им сказать, что им нужно переделать примерно все, начиная эдак с С++11, и некоторых мелочей из C++98. Они столько фигни напридумывать успели, что в том виде, в каком они дополняют язык, он совершенно точно загнется. Самое интересное, что энтерпрайзу пофигу на их потуги, и по-настоящему серьезные и сложные вещи пишутся на классических плюсах, например игровые движки.

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

вроде как арифметика на итераторах не вполне совпадает с арифметикой указателей

и кста итераторы предназначены для итерирования (по вектору по дереву и вообще по произвольному графу) поэтому следующий итератор не обязан в общем быть больше предыдушего ?!?

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

Итератор выглядит как бесполезный слой абстракции

Только если считать что данные, которые выдает итератор лежат последовательно, что в общем случае неверно.

ya-betmen ★★★★★
()
Ответ на: комментарий от zx_gamer

final должен быть атрибутом. Они же придумали зачем-то «особый идентификатор» вместо этого.

final пришел как минимум из жавы(если мне память не изменяет). и быстро распространился по планете. Обозначает то, что данный обьект уже не может быть расширен или переопределен. Это не вспомогательнай атрибут, а полновесный спецификатор, навроде override или inline. может быть массово использован при проектировании и потому делать его атрибутом со специальным синтаксисом - портить внешность вашего кода.

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

Вот скажите ещё что ни разу в жизни «delete this» не приходилось делать…

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

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

Зачем добавлять [[такие]] атрибуты, когда все используют __attribute__ (такие) атрибуты

Потому что стандарт надо прочитать. Хотя бы на сишечку.

Лыжи - это зарезервированные ключевые слова имплементации стандарта, с которыми надо избежать конфликтов.

LamerOk ★★★★★
()
Ответ на: комментарий от i-rinat

Это просто чтобы показать какую херню придумали в ISO.

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

Концептуально он прав как минимум на половину. Конкретно тейк про то, что вся логика должна быть в методах объекта, довольно бредовый, так как это несовместимо с самой идеей обобщённого программирования (ну, либо я не вижу способа совместить с сохранением всех статических проверок времени компиляции). Но вот то, что у STL всратый публичный интерфейс, т.к. она имела целью "математическую" полноту, а не удобство использования - это уже давно общепризнанный факт.

Конкретно find в 99% случаев нужен по всему контейнеру, а не по подмножеству. И ситуация настолько плоха, что единственное существующее стандартное решение - std::ranges::search.

LamerOk ★★★★★
()
Ответ на: комментарий от i-rinat

А если тебе во второй половине вектора искать надо,

T *find(const T& value, T *since = NULL, T *finish = NULL) const
T *find(..., T *since = NULL, ...) const
T *find(..., T *since = NULL, ...)
T *find(T *since = NULL)
T *since = NULL

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

final должен быть атрибутом.

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

Что-то мне кажется, это взаимоисключающие параграфы, нет?

hobbit ★★★★★
()

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

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

Имхо любой новый проект нужно начинать на самом свежем стандарте, на данный момент это C++23

В пет-проекте вы вольны делать что вздумается, хоть на ушах стоять. Для чего-нибудь более серьёзного выбор tool-chain и стандарта должен быть куда как более осмысленным, и зачастую будет «спущен сверху». Лично я не фанат идеи «быть на острие», и скорее ярый сторонник подхода «нет сынок, мы спустимся очень медленно, и отымеем их всех».

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

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

Unreal Engine compiles with a language version of C++20 by default and requires a minimum version of C++20 to build.

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

Что-то мне кажется, они не оценят, если им сказать, что им нужно переделать примерно все, начиная эдак с С++11, и некоторых мелочей из C++98.

Ну такие-то высказывания конечно не нужны. Такого и без тебя целый Интернет.

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

Ни разу не видел.

Странный аргумент.

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

Это говно какое-то, а не движок. Эти идиоты сделали а) thread pool для всех задач в движке и тратят больше времени на синхронизацию, чем выигрыш от многопоточки (вы что собрались на ЦП такого обрабатывать, чтобы вам нужен был thread pool для всех задач?), б) GC (что само по себе странно для C++), который уронит все, если вы попробуете хотя бы где-нибудь сделать static переменную.

Я думаю этих обстоятельств достаточно, чтобы понять, что люди которые пишут новый UE не знают ни C++, ни многопоточное программирование.

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

Да ты, что?

Да я кто.

Это все не описано в стандарте?

Это всё, и многое другое, описано в стандарте как implementation defined.

Если тебя забанили в стандарте, то вот:

6.4.3
Identifiers
6.4.3.1
General
...
7
Some identifiers are reserved.
— All identifiers that begin with a double underscore (__) or begin with an underscore (_)
followed by an uppercase letter are reserved for any use, except those identifiers which are
lexically identical to keywords.
— All identifiers that begin with an underscore are reserved for use as identifiers with file scope
in both the ordinary and tag name spaces.
Other identifiers may be reserved, see 7.1.3.

...

7.1.3
Reserved identifiers
1
Each header declares or defines all identifiers listed in its associated subclause, and optionally
declares or defines identifiers listed in its associated future library directions subclause and identifiers
which are always reserved either for any use or for use as file scope identifiers.
— All potentially reserved identifiers (including ones listed in the future library directions) that
are provided by an implementation with an external definition are reserved for any use. An
implementation shall not provide an external definition of a potentially reserved identifier
unless that identifier is reserved for a use where it would have external linkage. All other
potentially reserved identifiers that are provided by an implementation (including in the
form of a macro) are reserved for any use when the associated header is included. No other
potentially reserved identifiers are reserved.
LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Конкретно тейк про то, что вся логика должна быть в методах объекта, довольно бредовый, так как это несовместимо с самой идеей обобщённого программирования

Да, именно так. Потому что концепция «обобщенного программирования» херня полная. Это, конечно, замечательно, что у вас есть «универсальный» std::sort, но отсортировать std::list<T> им нельзя. Для этого нужен особый алгоритм.

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

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

Почитайте раздел [cpp.predefined].

Прочитал. Я не вижу там ни одной запятой про твои фантазии.

Кроме того, что явно объявлено в стандарте.
того, что явно объявлено в стандарте.
что явно объявлено в стандарте.
явно объявлено в стандарте.
объявлено в стандарте.
объявлено
явно
в стандарте.

Ты стандарт-то вообще видел?

6
Some standard headers define or declare identifiers that had not been present in previous versions
of this document. To allow implementations and users to adapt to that situation, they also define a
version macro for feature test of the form __STDC_VERSION_ XXXX_H__, where XXXX is the all-caps
spelling of the corresponding header <xxxx.h>. These version macros expand to one of many values
detailed in the subclauses of Annex M such as 202311L and 202ymmL.
LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk
16.8 Predefined macro names
1 The following macro names shall be defined by the implementation:
__LINE__ The line number of the current source line (a decimal constant).
__FILE__ The presumed name of the source file (a character string literal).
__DATE__ The date of translation of the source file (a character string literal of the form
«Mmm dd yyyy», where the names of the months are the same as those generated by the asctime
function, and the first character of dd is a space character if the value is less than 10). If the date of
translation is not available, an implementation-defined valid date is supplied.
__TIME__ The time of translation of the source file (a character string literal of the form «hh:mm:ss»
as in the time generated by the asctime function). If the time of translation is not available, an
implementation-defined valid time is supplied.
__STDC__ Whether __STDC__ is predefined and if so, what its value is, are implementation-defined.
__cplusplus The name __cplusplus is defined to the value 199711L when compiling a C++
translation unit.143)
2 The values of the predefined macros (except for __LINE__ and __FILE__) remain constant throughout
the translation unit.
3 If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a
#define or a #undef preprocessing directive, the behavior is undefined

shall be defined by the implementation

Должны быть определены. Не «могут быть определены реализацией», а «должны быть определены реализацией». То есть стандарт может диктовать какие сущности с __ обязаны быть поддержаны.

zx_gamer ★★★
()