- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
class UnitedFigure : public Figure {
Figure &f1;
Figure &f2;
public:
UnitedFigure (Figure &_f1, Figure &_f2) : f1(_f1), f2(_f2) {}
double distance_to(const Point &p) const override {
return std::min(f1.distance_to(p), f2.distance_to(p));
}
}
gost 16.09.2020 19:18 # 0
> прекрасную возможность выстрелить себе в ногу
Чем ссылочные поля отличаются от полей-указателей?
bormand 16.09.2020 19:20 # 0
gost 16.09.2020 19:24 # 0
bormand 16.09.2020 19:26 # 0
gost 16.09.2020 19:28 # +2
Cnapmak 16.09.2020 19:30 # +1
Pig 16.09.2020 20:22 # 0
defecate-plusplus 16.09.2020 19:40 # +1
bormand 16.09.2020 19:41 # 0
defecate-plusplus 16.09.2020 19:45 # 0
bormand 16.09.2020 19:46 # +1
MAKAKA 17.09.2020 02:44 # 0
?
Внутри main создает временный объект с 42, и должен бы по идее разрушиться сразу, но остается жить?
Кажется, до 11 такого не было, и надо было вручную делать
но это не точно.
MAKAKA 17.09.2020 02:58 # 0
хотя пишут ворнинг
defecate-plusplus 16.09.2020 19:36 # +1
в смысле не бывает
bormand 16.09.2020 19:39 # 0
gost 16.09.2020 19:40 # 0
UB. ССЗБ.
MAKAKA 17.09.2020 02:53 # +1
В С++ же нет нулл сейфти, это же не котлин. Ты обязан проверить, что указатель не указывает на говно, прежде чем покласть его результат в ссылку
https://govnokod.ru/26958#comment575830
gost 17.09.2020 08:28 # +1
MAKAKA 17.09.2020 11:59 # 0
ну ты же понял, что имелось ввиду, не?
Когда я пишу
int& foo = *some_shit_that_returns_null()
там под капотом в foo оказывается адрес null, и при следующем обращении случается бугор
Я не спорю, что UB. Просто забавно, что оно как-бы заметено под ковёр из за сахара.
gost 17.09.2020 12:09 # 0
В этом-то и дело. Багор случается сразу же, как только ты разыменовываешь nullptr. Просто его последствия начинают проявляться позже.
Перефразируя j123123 (https://govnokod.ru/26809#comment575323):
>>> Если ты в крестах используешь какую-то сраную ебучую хуйню, типа разыменования указателя, то ты сам дурак должен соблюдать предельную осторожность с этой хуйней, и вся ответственность за segmentation fault и прочие подобные спецэффекты лежат на тебе. И нехуй в этом винить ссылки
MAKAKA 17.09.2020 12:19 # 0
Сразу случается UB, а багор случается чуть позже (хотя наверное может и сразу случиться в теории)
Я так понимаю, что именно это им не нравится.
3.14159265 16.09.2020 20:19 # 0
На как по мне это сахарок с ёбнутыми значками.
guest8 17.09.2020 02:16 # −999
bormand 17.09.2020 12:17 # 0
guest8 17.09.2020 12:22 # −999
j123123 17.09.2020 01:47 # +1
Всё там бывает, надо просто уметь. https://wandbox.org/permlink/N8evr3fCGLXDwEMt
Эти ссылки - просто сахарок над указателями
guest8 17.09.2020 02:17 # −999
j123123 17.09.2020 02:26 # +2
int *crap = (int *)malloc(100500);
на котором этот самый malloc обсирается и возвращает NULL, и потом в некую хуйню передается по ссылке crap[0]
и разыменование нулевой хуйни произойдет по факту не в том месте, где вызвана хуйня shit(crap[0]) а внутри самой функции shit(), которая с этой ссылкой будет что-то делать
MAKAKA 17.09.2020 02:48 # 0
>и потом в некую хуйню передается по ссылке crap[0]
лол, то есть можно передать уже говно, и узнать о том, что ты передал говно через три часа в другом месте?
По сути у тебя будет ссылка на нул, да)
Проверил. Такая хуйня скомпилировалсь, и упала. Какой багор))))
j123123 17.09.2020 03:00 # +1
Типа да, при передаче по указателю ты можешь нормально проверить, что указатель там не NULL, а по ссылке - хуй там. Но NULL там быть все же может.
Ссылки - просто сахарок над указателями для заедушных питушков, чтоб поменьше * писать
MAKAKA 17.09.2020 03:02 # 0
Если ты поклал в ссылку нул, то ты сам кривой.
В моем примере видимо надо так
j123123 17.09.2020 03:05 # 0
guest8 17.09.2020 03:11 # −999
j123123 17.09.2020 03:14 # 0
Можно, разрешаю. https://wandbox.org/permlink/edO6vo7o3ntWfZVJ
https://stackoverflow.com/a/9263728
MAKAKA 17.09.2020 03:16 # 0
а ты грил нельзя на хуйню проверить
j123123 17.09.2020 03:19 # 0
Ну так действительно нельзя
Там будет такая же хуйня с варнингом на строчке if (&bar == NULL)
prog.cc:11:18: warning: the compiler can assume that the address of 'bar' will never be NULL [-Waddress]
MAKAKA 17.09.2020 03:21 # 0
reference cannot be bound to dereferenced null pointer in well-defined c++ code
То есть катсинг-то сам по себе валиден (взять адрес того, на кого указывает ссылка), а вот проверка оного на нул -- варнинг
j123123 17.09.2020 03:23 # 0
Ну как бы да, компилятор имеет право считать, что раз у нас ссылка, то это точно что-то валидное, и NULL там быть не может.
MAKAKA 17.09.2020 03:26 # +1
компилятор имеет полное право мою проверку выкинуть, и код упадет
gost 17.09.2020 08:24 # +1
> *(int *)0
У тебя произошло UB, и что там дальше (да и раньше тоже) происходит — никого не волнует.
В well-formed программе на крестах nullptr в ссылке быть не может никогда.
j123123 17.09.2020 12:42 # 0
>> *(int *)0
>У тебя произошло UB
Если внимательно посмотреть, я использую особую опцию "-fno-delete-null-pointer-checks" от которой компилятор ложит хер на ту часть стандарта, которая запрещает разыменовывать NULL.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
> -fdelete-null-pointer-checks
>
> Assume that programs cannot safely dereference null pointers, and that no code or data element resides at address zero. This option enables simple constant folding optimizations at all optimization levels. In addition, other optimization passes in GCC use this flag to control global dataflow analyses that eliminate useless checks for null pointers; these assume that a memory access to address zero always results in a trap, so that if a pointer is checked after it has already been dereferenced, it cannot be null.
>
> Note however that in some environments this assumption is not true. Use -fno-delete-null-pointer-checks to disable this optimization for programs that depend on that behavior.
>
> This option is enabled by default on most targets. On Nios II ELF, it defaults to off. On AVR, CR16, and MSP430, this option is completely disabled.
>
> Passes that use the dataflow information are enabled independently at different optimization levels.
Но видимо этот флаг не запрещает компилятору предполагать, что ссылка не может быть с NULL.
gost 17.09.2020 12:53 # 0
j123123 17.09.2020 13:04 # 0
Надо просто ввести новую опцию -fallow-null-in-references
gost 17.09.2020 13:19 # 0
…то ты пишешь не на «C++», а на другом языке. С тем же успехом я могу ругать сишные структуры за какие-то багры в «Cython».
> где прочитать или записать хуйню по нулевому указателю вполне может иметь смысл
По Стандарту, кстати, никакого «нулевого» указателя не существует. Конкретный адрес nullptr и NULL выбирает платформа. Синтаксис «T * ptr = 0;» является синтаксическим сахаром:
§ 7.3.11/1 (N4842)
Именно поэтому читать-записывать по нулевому адресу тебе никто* не мешает:
* При условии, что там лежит валидный объект.
j123123 17.09.2020 13:23 # +1
Только вот тогда получается так, что на настоящем «C++» не пишет вообще никто, т.к. ни один компилятор крестоговна на данный момент не реализует стандарт на 100%
j123123 17.09.2020 13:26 # 0
https://modern-sql.com/standard/levels
> The SQL standard is huge. More than 4300 pages in its SQL:2016 incarnation. No single implementation can ever implement all features.0 Even in the early releases, such as SQL-92, the SQL standard defined different conformance levels so that vendors can claim conformance to a subset of the standard.
Почему кстати в стандарт крестоговна не ввели эти «conformance levels»? По-моему вполне логичный шаг.
gost 17.09.2020 13:32 # 0
Desktop 17.09.2020 13:40 # 0
ведь компилятор C++ не должен отвечать за другие языки.
в чём тут подвох
gost 17.09.2020 13:54 # 0
Desktop 17.09.2020 13:59 # 0
если у него реально другой язык, почему крестовый компилятор успешно компилирует такие исходники?
может, проблема просто в обилии UB'ов?
gost 17.09.2020 14:25 # 0
Термин — да, поведение — нет.
Как только в твоей программе случается UB — она перестаёт быть валидной программой на «C++», для которой Стандарт определяет какое-либо поведение.
> почему крестовый компилятор успешно компилирует такие исходники?
Потому что для программы с UB крестовый компилятор может делать что угодно!
> может, проблема просто в обилии UB'ов?
Это совершенно другая проблема.
Desktop 17.09.2020 14:27 # 0
то есть компилятор C++ может взять код не на C++ и скомпилировать из него какую-то ебалу
хорошо, что я на таком не пишу
bormand 17.09.2020 14:29 # +1
gost 17.09.2020 14:39 # 0
Как, впрочем, и няшная сишка: там тоже есть UB и оно точно так же может через карман укусить за яйца. С другой стороны, в §J.2 (N2346) приведён полный список сишных UB, так что их можно более-менее заучить и не допускать. С третьем стороны, этот список занимает десять страниц A4.
bormand 17.09.2020 14:40 # +1
Емнип, там офигенные вещи были в духе "название хедера не должно начинаться с цифры". Вот назовёшь хедер 1.h и получишь UB.
Desktop 17.09.2020 14:42 # 0
ломалось бы на этапе линковки или даже раньше
guest8 17.09.2020 20:25 # −999
bormand 17.09.2020 20:29 # 0
guest8 17.09.2020 20:30 # −999
bormand 17.09.2020 20:32 # 0
Ну либо вместо голого указателя возвращать какой-нибудь non_null_ptr<T>. Или ссылку, лол.
guest8 17.09.2020 20:34 # −999
bormand 17.09.2020 20:35 # 0
Я её выдумал. Но пишется за пару минут. В конструкторе проверишь, что не нулл и бросишь исключение. А дальше можно таскать без проверок и потерь пирфоманса.
guest8 17.09.2020 20:35 # −999
bormand 17.09.2020 20:43 # 0
Ну по-хорошему да. Не верить же автору сторонней либы на слово? Тем более сишные либы так сигналят об ошибке и тебе один хер проверять. А в крестах тебе голый указатель не так уж часто возвращают.
gost 17.09.2020 20:41 # 0
Если ты уверен, что get_petuhz() тебе никогда не вернёт nullptr — можешь делать так безо всяких проверок. В этом и есть смысл крестов (да и няшной тоже): ты можешь делать «опасные» операции безо всяких проверок, если считаешь, что они всегда будут корректны.
Однако если твоя уверенность тебя подведёт и get_petuhz() таки вернёт nullptr — ты получишь UB, и дальше твоя программа может делать абсолютно что угодно.
MAPTbIwKA 18.09.2020 15:07 # +1
А потому что только Программист знает, что валидно, а что нет.
Он царь и бог, а не житель анально огороженной крепости с надсмотрщиком как в джава
rotoeb 18.09.2020 16:14 # 0
а я придерживаюсь тех же взглядов. Компилятор/интерпретатор должен только проверять корректность синтаксиса, и никак не обучать тебя каким-то типизациям и, тем более, заставлять тебя удалять неиспользуемые переменные (как в "Go").
bormand 18.09.2020 16:15 # 0
rotoeb 18.09.2020 16:17 # 0
Так даёт-то это что?
guest8 18.09.2020 16:20 # −999
bormand 18.09.2020 16:23 # 0
Pig 18.09.2020 23:39 # 0
Desktop 17.09.2020 20:34 # 0
библиотека это уже бинарь
guest8 17.09.2020 20:34 # −999
j123123 17.09.2020 13:42 # +1
Текст стандарта крестоговна написан на английском и не является строго формализованным описанием, так что там еще хуй поймешь, можно над каким-то пунктом рассуждать как жиды над торой, что там говностандартизаторы в этом пункте имели в виду. Надо написать четкую формальную спецификацию, чтоб никаких разночтений не было, потом уже говорить, что можно писать на каком-то мифическом «C++»
gost 17.09.2020 13:53 # 0
> Надо написать четкую формальную спецификацию
Написали. Называется «Стандарт».
> разночтений
Приведи реальный пример разночтений в Стандарте.
j123123 17.09.2020 13:58 # +1
Это не четкая формальная спецификация. Это текстовая человекочитаемая хуйня на естественном языке, которую можно по-разному понять и проинтерпретировать своим мозгом.
> Приведи реальный пример разночтений в Стандарте.
Могу привести реальный пример, когда обсуждают, что именно вот конкретно этот говнопункт в крестостандарте значит, и как его надо понимать
gost 17.09.2020 14:15 # 0
> Могу привести реальный пример
Ну приведи.
j123123 17.09.2020 14:26 # 0
> Давайте с memcpy, с ним проще. Я смотрю по C++17 draft, но для простоты и тех, кто не хочет грузить 1500-страничные пдфки, даю ссылки на онлайн-версию, где стандарт уже немного другой.
> Так вот, 6.8/2 и /3 говорят, что вы можете делать memcpy для объектов trivially copyable типов (в частности, если они не являются подобъектами), даже если они не содержат валидного значения. И как мы видим из 11.2/1, наличие конструктора по умолчанию никак не влияет на свойство trivially copyable.
> Надеюсь, этого достаточно, чтобы разобраться с memcpy.
> А вот с memset всё интереснее. Он в стандарте упоминается всего несколько раз, и все эти разы — без описания семантики. Поэтому вопрос о том, что разрешено делать с memset, является совсем неочевидным. Ответ «memset в коде на плюсах использовать нельзя вообще», похоже, стандарту не противоречит.
И в ответе:
> Ну в самом же деле, нельзя же ожидать, чтобы в стандарте были перечислены вообще все допустимые случаи использования любых комбинаций функций из стандартной библиотеки.
Какой багор )))
Поэтому я за «Brainfuck».
gost 17.09.2020 14:33 # 0
§ 21.5.3/1 (N4842)
Идём в «C standard», читаем:
(N2346)
Всё, никаких разночтений.
j123123 17.09.2020 14:37 # 0
gost 17.09.2020 14:43 # 0
bormand 17.09.2020 14:44 # 0
O_o
gost 17.09.2020 14:45 # +2
Какой багор )))
j123123 17.09.2020 14:50 # 0
j123123 17.09.2020 14:46 # 0
Надо четко написать, что такие-то функции ведут себя точно так же, как ведут себя функции Си такого-то стандарта. А что такое meaning какого-то хеадера сишки? Просто определение функций, а что они делает - хуй знает. Это вам не крестоговно, когда там какие-то шаблоны с кодом запилены.
gost 17.09.2020 14:50 # 0
>>> The memset function copies the value of c (converted to an unsigned char) into each of the first n characters of the object pointed to by s.
Тут разве что приебаться можно к «first n characters of the object pointed to by s», но это нужно хорошенько задрочить крестовый object representation или как его, а там дохуя листов A4 формального английского, который нашему отделу чтения и парсинга обрабатывать лень.
j123123 17.09.2020 14:56 # 0
contents - содержимое. Там содержатся какие-то определения функций. Т.е. инклудя <cstring> мы инклудим то же, что и в <string.h>
meaning - значение. Ну т.е. смысл того что заинклужено. А смысл в хедере там такой, что вот такие-то функции есть, которые принимают такие-то аргументы и возвращает такую-то хуйню. Хедер сам по себе не описывает то, что конкретно какая функция делает. Так что надо четко сказать, что функии, определенные в таком-то хедере, делают то же самое, что они делают в сишечке такого-то стандарта.
gost 17.09.2020 15:30 # 0
На самом деле хорошая приёбка, но, тем не менее, Стандарт может противостоять даже таким дотошным людям!
§ 2/2
> Ну может это означает что-то в духе
Всё есть в Стандарте.
> когда обсуждают, что именно вот конкретно этот говнопункт в крестостандарте значит, и как его надо понимать
И тем не менее, после качественной раскопки Стандарта разночтений выявлено всё ещё не было. Отсутствие строгого определения слова «meaning» полностью компенсируется примечанием 1.
MAKAKA 17.09.2020 15:33 # 0
gost 17.09.2020 15:36 # 0
j123123 17.09.2020 18:20 # 0
Научная фантастика и научная реальность в информатике
Эдсгер В. Дейкстра
...
Чуть раньше я упомянул плохую документацию системы как внутреннее ограничение надежности, с которой система может быть использована механически в более широком контексте. Теперь самое время указать, что привлечение технического писателя редко является выходом из положения; в сущности, это не более как признание того, что разработчики системы в некотором роде функционально безграмотны. Обычно даже целая армия технических писателей не может справиться с задачей, поскольку система становится столь сложной, что не поддается точному описанию.
j123123 17.09.2020 18:20 # 0
guest8 19.09.2020 23:38 # −999
Myxa 19.09.2020 23:41 # 0
guest8 19.09.2020 23:43 # −999
Myxa 19.09.2020 23:43 # 0
guest8 19.09.2020 23:44 # −999
bootcamp_dropout 19.09.2020 23:44 # 0
guest8 19.09.2020 23:47 # −999
bootcamp_dropout 19.09.2020 23:47 # 0
MAKAKA 20.09.2020 03:21 # 0
Если бы в браузер была встроена ада, то все бы на ней писали, и текли, и не жужжали, и меньше было бы в мире undefined, Nan и [Object object].
Потому что статическая типизация позволяет отловить больше ошибок на уровне комплияции. Это же очевидно. Именно потому MS изобрёл TS.
bootcamp_dropout 20.09.2020 10:18 # 0
это означает что бандл у меня поделен на файлы, файлы подгружаются асинхронно, для работы сайта в первую секунду нужен один, а все остальные догружаются в течении минуты, а какие-то через 10 минут
при этом в коде файлы считают друг друга модулями
как это реализовать на компилируемых языках?
rotoeb 20.09.2020 10:22 # 0
Хуяндл.
Myxa 20.09.2020 12:11 # 0
bootcamp_dropout 20.09.2020 12:20 # 0
меня наебали?
Myxa 20.09.2020 12:21 # 0
Ось сразу посылает нахуй, если DLL указана в таблице импорта. Но этот способ далеко не единственный.
Второй способ — вызов функций LoadLibrary и GetProcAddress. Этим способом можно подгрузить DLL в любой момент и не упасть, если она не загрузится.
А в «Линуксе» есть dlopen.
bootcamp_dropout 20.09.2020 12:24 # 0
bormand 20.09.2020 12:28 # 0
А если на помойке нашёл - ну подизасмишь.
bootcamp_dropout 20.09.2020 12:31 # 0
как мне метод позвать или функцию?
bormand 20.09.2020 12:32 # +1
bootcamp_dropout 20.09.2020 12:33 # 0
guest8 20.09.2020 14:43 # −999
bootcamp_dropout 20.09.2020 15:51 # 0
bormand 20.09.2020 15:52 # 0
Опыт и везение. Что ещё защищает сишника?
rotoeb 20.09.2020 15:53 # 0
bormand 20.09.2020 15:56 # 0
guest8 20.09.2020 16:40 # −999
bootcamp_dropout 20.09.2020 15:55 # 0
gost 20.09.2020 15:58 # 0
gost 20.09.2020 15:57 # +1
guest8 20.09.2020 16:41 # −999
Myxa 20.09.2020 17:33 # 0
guest8 20.09.2020 16:40 # −999
Myxa 20.09.2020 12:33 # 0
Myxa 20.09.2020 12:32 # 0
Список символов получить можно. А вот семантику параметров функций нужно знать. В JS ты же тоже не знаешь, для чего какой аргумент у функции из чужого скрипта.
bormand 20.09.2020 12:41 # 0
Как что-то плохое. Немного дизасмишь саму длл, немного дизасмишь или дебажишь проги, которые ее юзали.
Если там не дичь какая-то, то часто удаётся понять суть аргументов.
Myxa 20.09.2020 13:38 # 0
Малость дизасмишь проги, которые её юзали.
Много примеров использования получаешь.
Это в нашей чеховской-кибальчеховской все-все знают.
guest8 20.09.2020 14:39 # −999
guest8 20.09.2020 14:50 # −999
bormand 20.09.2020 15:22 # 0
MAKAKA 20.09.2020 15:29 # 0
или время запуска?
bormand 20.09.2020 15:38 # 0
Myxa 20.09.2020 00:06 # 0
MAKAKA 20.09.2020 03:16 # 0
guest8 17.09.2020 20:20 # −999
3.14159265 19.09.2020 01:46 # 0
j123123 так мастерски доёбуется до С++, что из него вышел бы отличный кретостандартизатор.
j123123 17.09.2020 15:23 # 0
gost 17.09.2020 14:53 # 0
Ну так там это и написано. Для каждого хедера из стандартной либы (что крестов, что няшной) есть отдельный раздел, в котором описываются meaning соответствующих функций.
В крестовом Стандарте в описании <cstring> даже ссылка есть на соответствующий пункт няшного («See also: ISO C 7.24»).
j123123 17.09.2020 14:59 # 0
Там же про meaning хедера говорится, а не про meaning функций.
Ну и вот мы тут как раз еще один пример получили, когда обсуждают, что именно вот конкретно этот говнопункт в крестостандарте значит, и как его надо понимать, как ты и просил в https://govnokod.ru/26958#comment575919
> даже ссылка есть на соответствующий пункт няшного («See also: ISO C 7.24»).
Мало ли что это может значить? Ну может это означает что-то в духе "ну вот может ну нахуй это крестоговно, вот посмотрите лучше стандарт сишки, там прикольней написано".
3.14159265 19.09.2020 01:41 # 0
Какая однозначность )))
j123123 19.09.2020 19:47 # 0
> int value_at_zero = *(int *)(1 - 1);
Тут кстати можно не согласиться.
Если хуйня «(1 - 1)» после вычислений дает то же, что и дает NULL (допустим если в хедере есть «#define NULL 0», и при этом из курса школьной математики нам известно, что «1-1=0»), то получим UB (даже если там валидный объект). Если «*(int *)(1 - 1)» дает ту же хуйню, что и «*(int *)nullptr» - получем ту же UB хуйню (даже если там валидный объект)
gost 19.09.2020 19:57 # +2
В этом и весь смысл: (1 - 1) и 0 в контексте нулевого указателя — это разные вещи. Простой нолик-литерал — это синтаксический сахар, к нулевому адресу не имеющий никакого отношения. Поэтому из NULL == 0 вовсе не следует, что (int *)(1 - 1) — это нулевой указатель.
> Если «*(int *)(1 - 1)» дает ту же хуйню, что и «*(int *)nullptr» - получем ту же UB хуйню
А так будет только тогда, когда компилятор считает нулевой адрес за nullptr. Очевидно, если на какой-то платформе нулевой адрес валиден, то компилятор nullptr в него раскрывать не будет. Ну, если его не лалки анскильные писали, конечно.
bormand 19.09.2020 19:58 # +2
gost 19.09.2020 20:02 # +1
Myxa 19.09.2020 20:10 # 0
bormand 19.09.2020 20:13 # +1
Какой нуллптр )))
Myxa 19.09.2020 20:16 # 0
guest8 19.09.2020 20:18 # −999
gost 19.09.2020 20:24 # +1
>>> There was a strong consensus among the CWG that only the literal 0 should be considered a null pointer constant, not any arbitrary zero-valued constant expression as is currently specified.
Причём до C++11 нулевым указателем считалась любое нулевое константное выражение, что приводило к такому багру:
guest8 19.09.2020 20:57 # −999
guest8 19.09.2020 20:02 # −999
Myxa 19.09.2020 20:11 # 0
guest8 19.09.2020 20:16 # −999
j123123 19.09.2020 20:56 # 0
Есть реальные примеры, где это были б разные вещи?
https://wandbox.org/permlink/awAHb63ePcdv8Jal - я что-то не нашел.
bormand 19.09.2020 20:57 # 0
j123123 19.09.2020 21:00 # 0
bormand 19.09.2020 21:01 # 0
guest8 19.09.2020 21:05 # −999
bormand 19.09.2020 21:12 # 0
guest8 19.09.2020 21:15 # −999
j123123 19.09.2020 21:05 # 0
bormand 19.09.2020 21:07 # 0
gost 19.09.2020 21:08 # 0
>>> A null pointer constant is an integer literal (5.13.2) with value zero
Ну и https://wg21.cmeerw.net/cwg/issue903 ещё.
j123123 19.09.2020 21:14 # +1
в крестах может вывести "sosnoole!\n" ?
Ну и хуйня ваши кресты.
gost 19.09.2020 21:22 # 0
> Ну и хуйня ваши кресты.
Ну а как ещё соблюсти два условия:
1) Иметь «нулевой» указатель nullptr, который на текущей платформе всегда будет невалиден;
2) Иметь возможность писать в любые адреса, поддерживаемые платформой, включая 0.
?
j123123 19.09.2020 21:29 # 0
В теории можно изобрести такую платформу, где абсолютно все указатели будут валидны, так что это условие по-сути своей - хуйня полная.
> 2) Иметь возможность писать в любые адреса, поддерживаемые платформой, включая 0.
Это можно было б решить какой-нибудь нестандартной хуйней, например специальным оператором разыменования или встроенной функцией, которая подразумевает что через нее можно можно и нулл разыменовать, и нихуя плохого в этом нет. Типа вместо
int hui = *(* int )0;
делаем
int hui = __buildtin_superduper_dereference((* int )0);
gost 19.09.2020 21:39 # 0
А на практике такая платформа нахуй не нужна.
Нулевой указатель нам нужен не для того, чтобы UB генерировать, а чтобы на него, внезапно, проверять. Вот есть у нас malloc(), она нам может вернуть либо указатель на выделенную память, либо nullptr/NULL в случае, если что-то пошло не так. Если у нас все указатели валидны — мы сосём хуй.
> специальным оператором разыменования
Ну и плодим никому не нужные сущности. Вместо этого разумнее было бы лишние сущности удалить, и за нулевой указатель считать только платформозависимый NULL/nullptr. Тогда мы спокойно можем писать по любому валидному числовому адресу, и никаких багров не возникает.
guest8 19.09.2020 21:42 # −999
gost 19.09.2020 21:48 # 0
Разумеется.
guest8 19.09.2020 21:49 # −999
bormand 19.09.2020 21:50 # 0
guest8 19.09.2020 21:52 # −999
gost 19.09.2020 21:53 # 0
§ 7.3.14/1 (N4842)
bormand 19.09.2020 21:55 # 0
Какой багор))
guest8 19.09.2020 21:56 # −999
gost 19.09.2020 21:56 # 0
gost 19.09.2020 21:54 # 0
В текущих крестах — да, реальный адрес будет 0xFFF….
> if(foo == 0)
0 неявно скастится к уко-ко-козателю и всё будет работать правильно.
j123123 19.09.2020 21:45 # 0
Эта хуйня без NULL-питухов решается - в malloc просто возвращаем структуру, которая состоит из bool и из поинтера. Если в буле false то значит malloc обосрался с выделением памяти, если в буле true то значит все норм, и из другого члена этот поинтер читаем и чето с ним делаем.
gost 19.09.2020 21:50 # 0
Только вот есть проблема: обычно размер указателя равен размеру регистра, поэтому твоя структурка в [er]?ax не поместится. Как результат — придётся на каждый вызов любой функции, потенциально возвращающей NULL, лишний раз дрочить память, а это пиздец пирфомансу.
guest8 19.09.2020 21:52 # −999
j123123 19.09.2020 21:54 # 0
gost 19.09.2020 22:00 # 0
j123123 19.09.2020 22:39 # 0
На практике нахуй не нужны языки, которые указывают, какие платформы нужны, а какие нет.
Если взять например 8-bit AVR говноконтроллеры и почитать memory map из даташита, то там на нулевых адресах хранятся значения регистров, т.е. регистры можно прочитать из памяти таким вот образом. Если используется malloc() хуйня, то конечно же она в регистрах нихуя выделять не должна, так что для обозначения того, что malloc() обосрался, вполне можно использовать адрес 0x0000, и для этого не надо никакой хуйни с гарантировано невалидными адресами, которые разыменовывать нельзя, достаточно просто адресов, которые никакая хуйня вернуть при нормальных условиях как валидное значение указателя не должна.
gost 19.09.2020 22:53 # 0
И шо, все остальные адреса валидные? Прямо от 0 до 0xFFF…?
> достаточно просто адресов, которые никакая хуйня вернуть при нормальных условиях как валидное значение указателя не должна.
Ок, хочу функцию
И чтобы она на тех контроллерах, на которых маппинг регистров в память поддерживается, возвращала мне этот адрес, а на тех, где не поддерживается — об этом сообщала. Вызывать её будем триллион раз в час.
j123123 19.09.2020 23:00 # 0
Ну вот тут https://scienceprog.com/avr-microcontroller-memory-map/ написано что начиная с RAMEND+1 адреса идет External RAM вплоть до 0xFFFF. Если ее реально всю дозаполнить реальной памятью, то тогда похоже что да, все адреса там так или иначе будут за что-то отвечать.
>чтобы она на тех контроллерах, на которых маппинг регистров в память поддерживается, возвращала мне этот адрес, а на тех, где не поддерживается — об этом сообщала.
А нахуя? Почему б тебе не узнать о неподдерживаемости на этапе компиляции (или на этапе чтения даташитов на конкретный говноконтроллер)?
gost 19.09.2020 23:17 # +1
Принимается. Да, у 16-битных (и меньше) контроллеров с лишней памятью проблемы. Их владельцам можно посоветовать либо использовать компилятор, производитель которого явно задекларировал, что в нём обращаться к NULL можно, либо хуярить асмовставки, благо из них обращаться к любым адресам никто не запрещает.
> А нахуя? Почему б тебе не узнать о неподдерживаемости на этапе компиляции (или на этапе чтения даташитов на конкретный говноконтроллер)?
Потому что надо.
Ну а вообще я к тому, что вот это:
>> достаточно просто адресов, которые никакая хуйня вернуть при нормальных условиях как валидное значение указателя не должна.
— плохое, неконсистентное решение. Если я могу прочитать данные по какому-то указателю, то почему он должен считаться невалидным?
guest8 19.09.2020 23:26 # −999
j123123 19.09.2020 21:36 # 0
А зачем для этого считать (void *)0 не тем же самым, что и (void *)(1-1) ? Ну пусть бы был какой-то nullptr который на одной платформе равен какому-нибудь 0xFFFFFFFF, на второй равен 0xDEADC0DE, на какой-то другой - еще какой-то хуйне, зачем его синонимировать с литералом 0? Чтоб с сишкой была совместимость?
bormand 19.09.2020 21:45 # +2
В крестах же NULLа не было в отличие от сишки.
gost 19.09.2020 22:06 # +1
«GCC» Стандарт понимает правильно и выдаёт вышеуказанные ошибки. А вот «Visual Studio» последней версии на них кладёт болт и успешно компилирует все три примера. Какой багор )))
gost 19.09.2020 22:11 # 0
«GCC» всё делает правильно и выводит «Pointer!/Pointer!/.../...»: https://wandbox.org/permlink/5HqRbFjgqNgUraDk.
А вот «Visual Studio» анскильно выдаёт четыре «Pointer!»: https://gcc.godbolt.org/z/W8hdY7 (cout заменил на няшный puts, а то там пиздец килобайты асма вылезли). Какой багорище )))
bormand 19.09.2020 21:57 # 0
Даже если у тебя какая-то платформа, где нулл можно юзать, ну положи туда какую-то структуру, на которую ты никогда не будешь брать указатели, которые могут быть невалидными. Ту же таблицу прерываний. Всяко что-то такое у тебя есть.
И не надо портить платформу и городить костыли на ровном месте.
И явный UB про разадресацию nullptr тоже можно убрать. Он ничем не отличается от любого другого указателя на мусор.
gost 19.09.2020 22:03 # 0
Какие костыли-то? Отдельный NULL/nullptr без привязки к конкретным числам — вполне себе заебись решение.
> И UB про разадресацию nullptr тоже можно убрать.
UB нельзя убирать, UB — это священная корова оптимизации!
bormand 19.09.2020 22:09 # 0
А UB про "специальное значение", имхо, пользы не приносит. Только вред и уязвимости в духе выбрасывания проверки на нулл потому что я уже обратился.
guest8 19.09.2020 22:14 # −999
bormand 19.09.2020 22:17 # 0
Таблица прерываний, загрузочный код и т.п.
Т.е. к нулю вроде и есть обращения, но их буквально пара штук на всю ось и они никогда не содержат проверку на нулл.
gost 19.09.2020 22:18 # 0
Зачем? Зачем?
Где тут повышения требования к скилльности прогера?
guest8 19.09.2020 22:23 # −999
gost 19.09.2020 22:28 # 0
Дык в любом языке с nullable ссылками дошли до того, что неплохо бы иметь специальное значение для пустой ссылки.
> int* q = (int*)i; //вот что тут будет?
С принудительным кастом — указатель на адрес 0.
> if (q == NULL) //а тут что?
Зависит от платформы.
Проблема не в принудительном касте, проблема в неявном. По-хорошему, надо было полностью запретить неявные касты из любых чисел в указатели. Хочешь инициализировать указатель пустым значением — пиши «ptr = NULL», а не выёбывайся с «ptr = 0».
Но, разумеется, теперь Боржоми пить поздно, совместимость с сишкой выкинуть не получится.
guest8 19.09.2020 22:35 # −999
gost 19.09.2020 22:51 # 0
А без него, к счастью, не скомпилится даже сейчас.
guest8 19.09.2020 23:06 # −999
gost 19.09.2020 23:17 # 0
guest8 19.09.2020 23:20 # −999
gost 19.09.2020 22:17 # 0
Дык NULL — это по определению невалидный адрес.
> в духе выбрасывания проверки на нулл потому что я уже обратился
Дык уязвимость-то будет не в выбрасывании проверки на нулл, а в самом обращении. После обращения к указателю проверка на нулл полностью бессмыслена.
bormand 19.09.2020 22:29 # 0
Скажем так, это просто адрес, который не может быть выделен аллокатором, описанным в стандарте (ну и не может принадлежать локалке и т.п.) Поэтому я его могу юзать как маркер пустоты или как маркер ошибки. И это удобно для всяких структур данных.
Но он, имхо, ничуть не более невалидный, чем указатель на какой-нибудь ROM или MMIO, который я тоже по стандарту получить и юзать не могу, лол.
Зачем его делать пиздец-пиздец невалидным и особенным - я х.з.
gost 19.09.2020 22:49 # 0
Дык он и никакой не особенный. Обращение к нему — точно такое же UB, как и обращение к любому другому невалидному адресу.
>> В код по ошибке просочилось чтение.
>> А дальше пошло исполнение кода.
Какое исполнение-то? Чтение тебе кинуло SIGINT и всё, привет.
bormand 19.09.2020 22:50 # 0
На то и UB. Невалидный согласно стандарту адрес вполне может быть физически валидным.
bormand 19.09.2020 22:52 # 0
Почему нулл то в этом плане особенный? Потому что весь код засрали проверками на него, а теперь тормозит?
gost 19.09.2020 22:56 # 0
А какие ещё адреса согласно Стандарту невалидны?
> Почему нулл то в этом плане особенный?
Потому что компилятор не знает и знать никак не может, какие адреса у тебя там валидные, а какие нет.
Откуда компилятор должен узнать, что по 0x1234 у тебя ничего валидного не лежит?
bormand 19.09.2020 23:41 # 0
bormand 19.09.2020 22:40 # +1
В код по ошибке просочилось чтение. Дальше была проверка, которая остановила бы код. Но гцц ее выкинул. А дальше пошло исполнение кода.
Обращение к *p не должно создавать факт "p не нулл", имхо.
gost 17.09.2020 08:50 # +2
§ 9.3.3.2/5 (N4842)
Так что жаловаться на null в ссылках — это как сделать строку без \0 в конце, а потом ругать «strlen()» за то, что она падает.
bormand 17.09.2020 10:08 # 0
gost 17.09.2020 10:30 # 0
> и устроить true == false
Кстати, в прошлом году на ГК это обсуждали: делали memcpy() в буль-буль переменную и наблюдали за весёлыми эффектами на разных компиляторах. Кажется, там ещё какой-то конпелятор проверял чётность буль-буля и 2 считал за false.
guest8 17.09.2020 02:02 # −999
YpaHeLI_ 17.09.2020 10:48 # 0
Присвоишь ты в это поле ссылку на объект в другом скопе, он уничтожится и получишь SEGFAULT, и будешь потом долго искать в чем дело, а найдя будешь переписывать свой монолит.
> по твоему поля всегда должны копироваться чтоли?
умные указатели, RAII, а не это уж точно.
gost 17.09.2020 10:50 # 0
, кроме того, что ссылки тебе гарантируют null-safety?
MAKAKA 17.09.2020 12:12 # 0
А ссылку не можешь (точнее можешь, но компилятор может такую проверку выкинуть, бо будет считать, что она всегда фолс))
Но я не защищаю эту позицию. Я не крестовик, но мне тоже нравится null safety. Во всяком случае в джавах и котлинах мне нравится знать, что поле никогда не может быть нулом, и не проверять его каждый раз, как дурак
gost 17.09.2020 12:15 # 0
> Во всяком случае в джавах и котлинах мне нравится знать, что поле никогда не может быть нулом, и не проверять его каждый раз, как дурак
Подтверждаю.
Кстати, если уж развивать мысль — в «Ко-ко» же можно какой-нибудь грязной рефлексией в поле типа T записать null?
bormand 17.09.2020 12:16 # 0
guest8 17.09.2020 12:25 # −999
guest8 17.09.2020 12:45 # −999
MAKAKA 17.09.2020 12:46 # 0
MAKAKA 17.09.2020 12:46 # 0
bormand 17.09.2020 13:40 # 0
MAKAKA 17.09.2020 13:43 # 0
наплодили шлюхоаккаунтов, ну шо за люди, блять...
guest8 17.09.2020 13:50 # −999
MAKAKA 17.09.2020 14:09 # 0
ну на
ХРЮЮЮЮ
guest8 17.09.2020 14:19 # −999
guest8 17.09.2020 20:15 # −999
MAKAKA 17.09.2020 11:57 # 0
С ссылками и поинтерами вообще такая проблема есть в крестах, угу.
>умные указатели
Ну так используй умные указатели в полях, это же можно наверное?
gost 17.09.2020 12:02 # 0
Умные указатели нужны тогда, когда наш класс владеет объектом (за исключением std::weak_ptr, но это специфическая штука). А когда класс должен ссылаться на какой-то объект, очевидно, приходится использовать либо указатели (и ловить багры от nullptr), либо ссылки (и ловить багры от невозможности изменить объект, на который указывает ссылка).
MAKAKA 17.09.2020 12:03 # +1
bormand 17.09.2020 12:14 # 0
YpaHeLI_ 17.09.2020 20:50 # 0
bormand 17.09.2020 20:52 # +1
gost 17.09.2020 20:54 # 0
bormand 17.09.2020 20:55 # 0
gost 17.09.2020 21:02 # 0
> Для данного класса какой-нибудь unique вполне сойдёт.
А вот не факт. Я, может, не хочу ебать кучу, а хочу
.
bormand 17.09.2020 21:06 # +1
MAKAKA 17.09.2020 21:52 # 0
Десктоп, было такое?
правда что именно там было на стеке яне помню
bormand 17.09.2020 21:56 # 0
Тогда всегда пишешь как для кучи, а конпелятор сам разберётся.
Жабий жит вроде умеет такое. Кресты пока нет, но собираются добавить в стандарт возможность выпиливать пару new/delete.
MAKAKA 17.09.2020 21:57 # 0
потому что иначе был бы ад: яхочу передать структуру из двух интов (например Point), и должен в кучу срать?
нувот джит умеет доказать, что ссылка не утекает и вот
bormand 17.09.2020 21:59 # 0
MAKAKA 17.09.2020 22:00 # 0
типа я такой сру в кучу, а он ESP вертит
bormand 17.09.2020 22:02 # 0
3.14159265 17.09.2020 23:24 # 0
Апгрейд мув-семантики?
Они ещё предлагают похожую технику, если конструктор+деструктор тривиальный, то объект можно копировать через memcpy.
Особенно поможет стд::вектору, чтобы при удвоениях делать realloc.
Desktop 17.09.2020 22:10 # 0
gost 17.09.2020 12:16 # 0
>>> А, ну да, это ж кресты, тут думать надо.[/color]
j123123 17.09.2020 13:53 # 0
>думать надо.
C++ — довольно таки примитивное, но монстровое поделие, полное исторически сложившихся нелепых нагромождений. Человек, который хорошо в нем ориентируется — это хорошее зубрилко, а не хороший программист. Умение героически преодолевать трудности, которые создает твой собственный инструмент, вместо того, чтобы решать непосредственно прикладную задачу, в современном мире ценится разве что только среди прыщавых сосок. Работодатель же это сомнительное умение не ценит, и совершенно справедливо.
guest8 17.09.2020 20:22 # −999
guest8 17.09.2020 20:37 # −999
MAKAKA 17.09.2020 20:37 # 0
gost 17.09.2020 20:37 # 0
MAKAKA 17.09.2020 20:37 # 0
MAPTbIwKA 17.09.2020 20:50 # +2
блять
как ты мог насоздавать фаек с детским паролем, ты ж не уёбок
MAKAKA 17.09.2020 21:56 # 0
Ты вот кладешь телефон на работе на стол? Как ты знаешь, что его не спиздят?
Pig 17.09.2020 22:05 # +1
MAPTbIwKA 17.09.2020 22:08 # 0
и машину всегда лочу
нахуй надо
bormand 17.09.2020 22:09 # 0
Даже когда один дома?
MAPTbIwKA 17.09.2020 22:15 # 0
bormand 17.09.2020 22:17 # 0
MAPTbIwKA 17.09.2020 22:19 # 0
зато пароль у меня не 123
bormand 17.09.2020 22:24 # 0
Ну вот зачем ты выдал инфу о своём пароле? Теперь на 1 вариант меньше перебирать.
MAPTbIwKA 17.09.2020 22:27 # 0
раки набрутили пароли со старых древних акков и время от времени с них срут
набрутили потому, что пароли там типа 123
Макака каждый раз, когда начинают срать, первым кричит, что "опять эти раки"
но всем файкам поставил именно 123 в качестве пароля
наверное, чтобы ракам было через пару лет удобнее набрутить ещё учёток
bormand 17.09.2020 22:55 # +1
guest8 19.09.2020 01:52 # −999
bootcamp_dropout 17.09.2020 22:29 # 0
guest8 17.09.2020 22:18 # −999
guest8 20.09.2020 05:01 # −999
gost 20.09.2020 07:24 # 0
3oJIoTou_xyu 20.09.2020 07:01 # 0
guest8 19.09.2020 01:52 # −999
guest8 19.09.2020 21:16 # −999
bormand 19.09.2020 21:17 # 0
guest8 19.09.2020 21:17 # −999