- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
#include <stdio.h>
struct{int a; float b;} test()
{
return (typeof(test())){1337, 666.666};
}
int main()
{
auto a = test();
printf("%d %f\n", a.a, a.b);
return 0;
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
0
#include <stdio.h>
struct{int a; float b;} test()
{
return (typeof(test())){1337, 666.666};
}
int main()
{
auto a = test();
printf("%d %f\n", a.a, a.b);
return 0;
}
В стандарт C23 добавили auto и теперь можно писать такую хуйню. В "Clang" работает: https://godbolt.org/z/GG3addqPb
а мржно пейсать auto auto(auto auto)?
Ведь если какой-то петух напишет допустим
то кто-то может вызвать такую говнофункцию с типом "int" а кто-то с типом "double" и это будет две разные функции, а прототип всего один. Короче хуйня какая-то. В Си нет такого, чтоб было несколько функций с одним именем
И возвращать auto она тоже не может т.к. из прототипа нихуя не ясно, какую хуйню она там может возвращать, и тогда если у нас объявлен лишь прототип
Компилятору нихуя не будет ясно, какое говно оно вернет. Это тебе даже крестопараша не скомпилирует.
Увы, можно использовать только в макросах. В функциях нельзя из-за отсутствия перегрузки.
«PHP» выводит типы, но во-первых, снаружи ничего не видно (неявность), во-вторых он тут же приведёт тип к другому, если можно (слабость).
«Если можно» — это ещё не слабость. Приводить «float» в «double» может и строгий язык, например.
Слабость возникает, когда язык позволяет неявно приводить типы с потерей информации — например, массив в строку, — либо с возможными ошибками.
Но в целом, это довольно размытые термины без точных границ, поэтому и хрен с ними.
опять плюнул, опять сказал "эх" и ушел. И Бог с ним. Расскажу лучше про Илью
Павловича.
Предлагаю ввести термин "ебанутая типизация". Например, когда ты можешь унсигнеду присвоить сигнед, или пойнтеры разных типов присваивать — это слабая; а когда петух складывает строку с числом, а потом делит на число и у него ничего не падает — это ебанутая
> 'петух'+42
'петух42'
> ('петух'+42)/3
NaN
Ничего не упало, никаких исключений не выкинуло.
Кто говорил, что в PHP нету типов?
P.S. А если заменить плюс на точку (конкатенацию), то отрабатывает, переводит число в строку: ('петух' . 42) возвращает 'петух42'.
Но вот разделить строку на число не может, снова TypeError.
Даже допустим, что c — точно число и не ноль.
"Вывод типов" при динамической типизации не нужен, т.к. в динамически питузированных языках есть ровно один тип*. Соответственно, PHP ничего там не выводит.
* С точки зрения компилятора и рантайма, а не с точки зрения фантазий программиста
Это в bash и в TCL всё — строка.
То, что некоторые операции могут в рантайме кидать исключение, если пытаться сложить арбузы с килограммами, это просто runtime exception. Никакой системой типов здесь и не пахнет.
Система типов, по определению — это механизм, который в compile time запрещает код, приводящий к таким исключениям.
Вывод типов — это дополнительный механизм в компиляторе, который позволяет опускать аннотации.
Какое-то хуевое определение. Можно сделать компилируемый язык программирования с типами, который нихуя в compile time не запрещает на основании типов, а при попытке посчитать синус из строки, программа может упасть или начать какую-то хуйню делать (например, начать удалять случайные файлы на диске). Наличие типов не обязывает их тайпчекать, да и сами типы могут быть нужны не только чтоб не компилировать что-то, что эти типы нарушает
Такое определение даёт TAPL. Если в точности: "A type system is a tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute."
> компилируемый язык программирования с типами, который нихуя в compile time не запрещает на основании типов
Вообще ничего не запрещает? Тогда это язык без системы типов.
Значит там плохое определение. Спецификатор _Atomic не "proving the absence of certain program behaviors", он наоборот описывает особенности поведения, которые нужны для этой переменной.
> Вообще ничего не запрещает? Тогда это язык без системы типов.
Не согласен. Я вполне могу представить язык (особо ебнутый диалект сишки), в котором есть типы, и в котором можно написать хуйню вида
и это успешно скомпилируется, но при запуске крашнется или посчитает какую-нибудь хуйню (например скастует адрес строки "Hello world" в double и посчитает синус из него). Типы при этом там будут
В рантайме могут быть, конечно. Это от компилятора зависит.
Мне кажется, что тип определяет множество операций над объектом.
Вот есть "указатель на чар".
Есть у него операция "взять синус"?
Ну если есть, то значит всё в порядке.
Если нет, то проверка типов должна его отстрелить.
Может в моем особо ебнутом диалекте сишке с особо слабой типизацией как раз всё скомпилируется. На каждый случай всегда будет существовать некий упоротый алгоритм неявного приведения типа одного говна в другое. Например, если функция принимает структуру str1 по значению, а ей пихают вместо структуры переменную типа double, оно будет байтики этого дабла интерпретировать как структуру, т.е. как если б кто-то объявил такую структуру, в него memcpy-нул этот дабл и передал в функцию.
> Мне кажется, что тип определяет множество операций над объектом.
Какие операции определяет спецификатор _Atomic в Си?
Если система типов не отловила невилидную операцию, значит это дырка в системе типов.
>оно будет байтики этого дабла интерпретировать как структур
Это не скомпилируется.
Если скомпилируется -- ты отключил систему типов.
>_Atomic
Операции изменения и чтения объекта из разных тредов без локов.
Си это не проверяет (в этом месте система типов си соснула).
В расте, например, это говно проверяется.
Может у меня в особом говнодиалекте Си все эти операции валидные. В любой непонятной ситуации делается reinterpret_cast, притом если размеры не соответствуют, то или там байтики обрежутся, или будет какой-то мусор в конце
> Если скомпилируется -- ты отключил систему типов.
Слабая типизация это не "ты отключил систему типов".
> Операции изменения и чтения объекта из разных тредов без локов.
Есть или нет там локи - implementation defined и зависит от хуйни, которую ты делаешь _Atomic. Если ты например атомарно хочешь поменять значение большой структуры, тебе без локов не обойтись
https://stackoverflow.com/a/57687787
> If your structure does not fit into a wide register, platforms usually implement these atomic types by using some kind of lock that is stored outside of your structure. If it does, they use the native capacities of the platform. Such properties may depend on your compiler options, in particular you'd have to ensure that these are the same for all your compiled objects.
Валидно брать синус от адреса структуры?
ну ок, значит никаких проблем нет. Система типов допустила валидную операцию.
>Слабая типизация это не "ты отключил систему типов".
Слабая типизация позволяет неявно превращать один тип в другой ради уменьшения бойлерплейта.
Это и есть отключение типизации в какой-то момент.
>Есть или нет там локи - implementation defined
Я имел ввиду лок снаружи.
Я, как пользователь объекта, могу вызвать на нем операцию без явной синхронизации.
Под капотом конечно может быть что угодно.
На каких-то платформамх там может быть префикс LOCK у инструкции (если одной инструкции хватит)
На других -- отключение прерырваний (если у тебя одно ядро, то вероятно хватит).
На третьих нет вообще нихуя, и нужно чуть-ли не спинлоки городить (если это там драйвер какой-нить )
Алсо, некоторые инсвтрукции атомарны сами по себе
Это всё правда детали реализации.
Нет. Нет типизации например в языке brainfuck. А когда на каждый случай есть ебнутое правило приведения типа, это "типизация есть, но есть ебнутые правила неявного приведения типов, которые всегда к какому-то типу что-то скастуют"
"типом' ты называешь подсказку комплиятора.
В таком случае, ключевое слово `register` и вот такая хйня являются типами
Существует два использования типов.
Типы-по-Снауту: какая-то хуйня для проверки корректности кода (ламерски выражась).
Типы-по-j123: какая-то хуйня, помогающая компилятору генерить более правильный (иногда просто корректный, или более оптимальный) код.
У нас в тайпсрипте есть только первые типы, например.
> Типы-по-j123: какая-то хуйня, помогающая компилятору генерить более правильный (иногда просто корректный, или более оптимальный) код.
Второе не исключает первое. Т.е. типы и для проверки какого-то неправильного поведения (когда в какую-то функцию передал не ту хуйню и компилятор насрал варнингами или вообще ошибку выдал) подходят.
> У нас в тайпсрипте есть только первые типы, например.
В TS точно доступны Uint8Array Uint16Array т.к. тупоскрипт это тупо надстройка над жабаскриптом. И если ты выбираешь между таким или таким массивом, ты наверное руководствуешься не тем, чтобы корректность кода проверять, а чтобы байтики экономить (или не экономить, если в 8 бит значения не влазят)
А если типы неявно приводятся (как в Бейсике, например, округляется плавающий питух при копировании в целочисленную переменную), то типизация есть, но слабая.
Обычно чем выше язык, тем более семантичные в нем операции
в Python нельзя использовать длину хуя как адрес в памяти, в сишке можно но нужно кастануть, а в асемблере вообще норм.
-Wall -Werror делает из скриптусишки что-то удобоваримое
``Типы'' в сишке без условного -Werror -Wall просто позволяют компилятору примерно почувствовать размер данных на стеке, знать, влезет ли переменная в регистр, какие инструкции нужно эмитить или можно опускать, и т.д. С точки зрения TAPL — это не система типизации, а какие-то аннотации для котогенератора.
Тогда, например, указатель будет соответствовать строке двухмерного массива номер R*cos(phi) и столбцу номер R*sin(phi).
Можно ещё придумать память с трёхмерной адресацией: с цилиндрической (добавится высота) или со сферической (добавится второй угол).
Являются ли проверяемые на стадии компиляции контракты (ассерты) системой типов?
If the type of the operand is a variably modified type, the operand is evaluated; otherwise, the operand is not evaluated.
https://en.cppreference.com/w/c/language/typeof.html
Я придумал, надо организовать соревнования: кто напишет самый непонятный кот. Назову его "IOCCC".
Как тебе идея?
https://www.youtube.com/watch?v=58Eff70zgjQ
Чеченская Гитара•3,7 млн просмотров
10 признаков того, что ВЫ ОДНОВРЕМЕННО думаете друг о друге Карл Юнг
Юнгианка
Новинка
1,8 тыс. просмотров
в древней сишке надо было указывать: лежит переменная на стеке (тн "автоматическая") или в регистре. И там `auto` означала "автоматическая".
Потом это стало поведением по умолчанию, и это слово убрали.
Или как строки были нультерминаторами... Ой, а это до сих пор так
Зато Ричи, молодец, заранее продумал, чем заниматься стандартизаторам: теперь каждый год они с друзьями собираются, надевают носочки и придумывают новую "безопасную" foo_s нкцию
у потсфикса есть
Сначала придумали strcat. Потом сказали, что небезопасно: функция может распидорасить оперативку, если ты не угадал нужный размер буфера.
Потом сказали: вот вам strncat — более безопасный вариант.
Потом сказали: нет, мы ошиблись, держите ещё более безопасный вариант — strncat_s.
А параллельно в MS решили навернуть свои безопасные варианты.
Ладно, размер буфера для strcat я могу предугадать, просто сложив размеры строк (ага, лишние вызовы с O(n)). Но как я угадаю размер, который потребует sprintf? Мне по сути для подсчёта длины нужно повторить алгоритм sprintf, но спекулятивно, без реального заполнения строки, а потом уже вызывать sprintf. Хорошо, что в asprintf это решили.
К слову, я ещё видел какие-то «безопасные» библиотеки для строк, только там не «n» и не «_s», а какие-то другие префиксы/инфиксы/суффиксы.
и ещё эта блядская любовь сишников к сокращениям до нечитаемости
>sbrk
Prd krt skrz drn, zprv zhlt hrst zrn
кстати, он устарел же. mmap
https://pbs.twimg.com/media/GvPhqMNWAAAIt16?format=jpg&name=large
Это же твой любимый персонаж. Крупный предприниматель, серьезный блоггер, опытный программист, и видный либертарианец.
И кстати: нет такого языка "дот нет"
может показаться, что это политизированный пост, но мы-то знаем, кого действительно обыгрывает эта ирония
Занять — это отнять (на время).
Одолжить — сделать кого-то своим должником.
Лучше бы писали «дать в долг» и «взять в долг», если путают.
https://pbs.twimg.com/media/Gu5O5CyWkAAPNRy?format=jpg&name=small