ru
Feedback
Блог*

Блог*

Открыть в Telegram

Блог со звёздочкой. Много репостов, немножко программирования. Небольшое прикольное комьюнити: @decltype_chat_ptr_t Автор: @insert_reference_here

Больше
1 925
Подписчики
+124 часа
+67 дней
-630 день
Архив постов
photo content

#prog #java #meme

#video Или немного о том, что из себя представляет это ваше программирование (метафорически). youtube.com/watch?v=cDA3_5982h8

photo content

То есть не только пошёл спать под утро, так ещё и вместо того, чтобы спать, дочитывал ЛВПГ. Нет, не жалею об этом.

🔁 Rezard
🔁 Rezard

Если есть единомышленники, то, наверное, есть и единокошленники?

photo content

#meme

Repost from N/a
photo content

photo content

Ну и напоследок о том, как можно эту функцию улучшить. В C++, в отличие от C, поддержка multi-character character literal является необязательной, поэтому конформная реализация C++ может попросту не скомпилировать эту функцию. Для того, чтобы улучшить переносимость между языками, можно убрать этот литерал и заменить sizeof'++'/2 на (sizeof'+'+sizeof'+').

#prog #c #cpp #моё Если вам вдруг понадобилось в рантайме выяснить, была ли ваша программа скомпилирована в режиме C или же C++, то вот непотокобезопасная функция, которая вернёт ответ в виде ноль-терминированной строки напрямую на большинстве систем:
char const* get_language() {
    static char s[] = "C++\?";
    s[sizeof s/sizeof'C'-sizeof'++'/2/sizeof'\?']=0;
    return s;
}

Как же это работает? В отдельной переменной записывается строка, в нужную позицию записывается признак конца строки, а затем строка возвращается. Всем пока. ... Нет, всё-таки, как это действительно работает? Первая строка объявляет переменную s и присваивает ей значение. Переменная s статическая, чтобы возвращаемый указатель не становился висячим сразу после возврата из функции. Строковые литералы в C и C++ являются массивами char-ов, включающими в себя неявно добавляемый на фазе трансляции терминирующий нуль-символ. s объявлена, как переменная типа char[]. Обычно тип в C(++) нужно выписывать целиком, но длину массива в объявлении переменной можно опустить, если её можно вывести из типа инициализирующего выражения — как в этом случае. Строка "C++\?" имеет четыре символа (четыре, потому что \? является escape-ом для ? (потому что триграфы)), поэтому с учётом конечного нуля получаем, что s имеет тип char[5]. Что же касается второй строки... Что ж, тут надо разбираться. Во-первых, sizeof является унарным оператором и, вообще говоря, не требует скобок. При этом у него приоритет выше, чем у арифметических выражений, поэтому в выражении ниже они и не требуются. Не то чтобы это было сильно важно для понимания, но не все об этом знают. Во-вторых, в этой строчке sizeof применяется к, в частности, литералу символа. Чему равно значение этого выражения? Казалось, это должно быть 1, поскольку стандарт C прямо диктует (а стандарт C++ вторит), что sizeof(char) равен 1. Но! Тут мы применяем sizeof к литералу символа, и тут кроется одно из отличий между C и C++, делающей эту функцию возможной: литерал символа имеет тип int в C и тип char в C++. Тут возникает вопрос, какой же размер у int. Если вы программируете не под микроконтроллеры, то на вашей целевой системе тип int наверняка имеет размер 4 байта. Строго говоря, это не всегда верно, поскольку размер int является implementation defined, но это настолько распространённое и работающее на практике заблуждение, что после появления 64-битных систем размер int остался на них 4 байта. Не смотря на то, что int по замыслу является целым числом нативного для машины размера, смена размера int на 64-битных платформах до 8 байт сломало бы слишком много программ. Итак, sizeof'C' и sizeof'\?' возвращает 4 для C и 1 для C++. sizeof s возвращают размер типа s. Для массива это размер в байтах. Так как s имеет тип char[5], sizeof s возвращает 5. Но вот что такое sizeof'++'? Нет, это не опечатка. В-третьих, малоизвестный факт заключается в том, что в C и C++ в литерал символа можно записать больше одного символа, и называется это multi-character character literal. То, как именно эти литералы отображаются на численные значения, зависит от реализации — но нам это и не важно, потому что эти значения мы всё равно не используем. А вот что важно — так это то, что и в C, и в C++ такие литералы имеют тип int. Так что sizeof'++' возвращает таки 4. С учётом изложенного выше, а также того, что оператор деления и в C, и в C++ является левоассоциативным, можно подсчитать, какие же получаются индексы в функции. Для C это 5/4 - 4/2/4 = 1 - 2/4 = 1 , поэтому присваивание записывает конец строки аккурат после первого символа C. Для C++ же 5/1 - 4/2/1 = 5 - 2/1 = 3 , потому присваивание записывает ноль после второго +. В третьей строке строка возвращается, и из-за объявленного типа массива деградирует до указателя на его первый элемент. Признаком конца строки в C является ноль-символ, поэтому все функции стандартной библиотеки считают возвращаемое значение строкой "C" в C и "C++" в C++ соответственно. Как видите, всё очень просто.

В вывеске часы работы указаны так Зима: 8:00-21:00 Лето: 8:00-22:00 Теперь загадка жака фреско: как эта аптека работает весной и осенью? :blobcatgooglyholdingitsheadinitshands:

Не плачь, ибо плачут только четырнадцатилетние девочки. Ты взрослый мужчина — рыдай!

Оказывается, пайдантик может молча дропнуть создание класса, если немного накосячить с объявлением Узнала я об этом при попыт
Оказывается, пайдантик может молча дропнуть создание класса, если немного накосячить с объявлением Узнала я об этом при попытке проверить работу алиасов. Если базовая модель объявляет поле, а наследник переобъявит его через присваиваение pydantic.Field(alias=...), но *не* укажет тайпхинт, пайдантик дропнет вообще весь класс, как будто его и не было никогда Причём достаточно одного такого поля, чтобы весь класс улетел в мусорку

#prog #python #suckassstory

K P A C U B O
K P A C U B O

Блог* - Статистика и аналитика Telegram-канала @dereference_pointer_there