После года разработки опубликован релиз свободного набора компиляторов GCC 13.1, первый значительный выпуск в новой ветке GCC 13.x. В соответствии с новой схемой нумерации выпусков, версия 13.0 использовалась в процессе разработки, а незадолго до выхода GCC 13.1 уже ответвилась ветка GCC 14.0, на базе которой будет сформирован следующий значительный релиз GCC 14.1...Подробнее: https://www.opennet.dev/opennews/art.shtml?num=59038
Под Байкал компилируется?
Тулчейны вроде есть...собери - проверь
а смысл компилировать под байкал?
Чтобы запустить в Qemu-ARM64
Байкал это попсовый ARM Cortex A, троллишко
> разрешение использования constexpr и auto при определении объектовНа кой auto в C? В C++ он нужен из-за монструозных template'тов.
Для уменьшения дублирования кода.
И прострела пяток поизящнее, как на JS :)
> И прострела пяток поизящнее, как на JS :)На самом деле применение автовывода типов может помогать бороться со слабостями системы типов.
Например, в C# есть атавизм в конструкции `foreach`: `foreach(ItemType item in collection)` неявно приводит элементы `collection` к типу `ItemType`. Поэтому возможность писать `foreach(var item in collection)` позволяет перенести часть ошибок с этапа выполнения на этап компиляции.
В Си тоже есть такие слабости типизации, которые могут быть устранены умелым применением `auto`.
> На самом деле применение автовывода типов может помогать бороться со слабостями системы типов.И обувает статический анализатор на возможность проверить баганул ли тут кодер или нет. Если кодер явно заказал тип и он не сощелся, тут почти наверняка зарыт баг.
А если там auto написано - оно такой себе catch all. И вон то уже отловить не катит. А чтоб совсем не скучать в сях раньше был auto но это _другой_ auto и означал он иные вещи. А теперь счастливой отладки, и попробуйте угадать какой auto имеется в виду, старый или новые :)
> Например, в C# есть атавизм в конструкции `foreach`: `foreach(ItemType item in collection)`
> неявно приводит элементы `collection` к типу `ItemType`.Софт на шарпее вообще любит крайне неочевидно баговать, течь и проч и отлаживать его занятие очень на любителя. Неявная автоматика один из замечательных методов прострела себе пяток.
> В Си тоже есть такие слабости типизации, которые могут быть устранены умелым
> применением `auto`.Например как? Обычно им пользуются чтобы код лаконичнее сделать. Это конечно достигается, но ценой потери декларации намерений кодера в этом куске кода.
> Софт на шарпее вообще любит крайне неочевидно баговать, течь и проч и отлаживать его занятие очень на любителя. Неявная автоматика один из замечательных методов прострела себе пяток.Очень интересно было бы пример услышать. Я думаю, ты выдаёшь желаемое за действительное.
Дебаггер работает отлично, средства анализа кода лучшие из всего, что представлено на рынке. Решарпер, рослин. Райдер и visual studio или vocoder как среды разработки. Статическая типизация везде. Есть даже di контейнер, который на этапе компиляции не пропускает забыть регистрацию.
Что тебе ещё надо?
Чего тебе ещё надо?
> Очень интересно было бы пример услышать. Я думаю, ты выдаёшь желаемое за
> действительное.Например малоочевидные утечки памяти в мало-мальски крупных дотнет программах просто норма жизни. И хрен поймешь, GC это протупляет или проблема серьезнее.
> разработки. Статическая типизация везде. Есть даже di контейнер, который на этапе
> компиляции не пропускает забыть регистрацию.Однако в целом это переросточный неспешный урод с страшноватым синтаксисом и проблемами перфоманса. Вплоть до того что LSE оказалось дешевле купить тиму сишников чем накидывать десятки миллионам тем кто так и не смог обеспечить обещаную латенси.
> Что тебе ещё надо?
> Чего тебе ещё надо?Потанцевать на могилке всего этого барахла. Что характерно даже майки наверное депрекейтнут это в пользу того же хруста.
> Например малоочевидные утечки памяти в мало-мальски крупных дотнет программах просто норма жизни.Это не общеизвестный пример. Есть ссылка на баги в таких проектах?
Я под НДА, но проекты на моно у нас текут. Могу сказать только что там дохрена-дохренища строковых манипуляций.
> Это не общеизвестный пример. Есть ссылка на баги в таких проектах?Те проекты - confidential/proprietary и сослаться на это вообще совсем не вариант. Да, гамно с ломовыми утечками памяти, проблемами перфоманса и кучей багов можно получить и за весьма приличные деньги.
А опенсорсных крупных проектов на дотнете я особо и не знаю. Крмое может разве что самого mono. Я вообще не понимаю нахрена оно такое надо. Майки походу тоже, с одной стороны хруст зажмет, с другой веб, и окажется это ни два ни полтора очередным deprecated, все как майкрософт любит.
Всегда удивляло что находятся люди, которые избыточный код считают дополнительной проверкой.
> Например как?Например если взять следующий код без авто.
short i = -3;
unsigned short u = i;Тут будет неявное преобразование типа. С авто его не будет.
short i = -3;
auto u = i;
> short i = -3;
> unsigned short u = i;При том если вы написали unsigned вы реально имели в виду намерение поработать с положительными числами и дальнейший код, вероятно, уповал на данное допущение. За вон то - можно варнинг в два счета получить, особенно если вас хватит на -Wconversion.
> Тут будет неявное преобразование типа. С авто его не будет.
И варнинг за назначение знакового беззнаковому, что явно баг.
> short i = -3;
> auto u = i;А вот тут варнингов не будет, но если вы вон там unsigned писали, вероятно, дальнейшая логика этого хотела, но вы заныкали это намерение и вот тут варнинга уже не будет. Добро пожаловать в мир багов. И спасибо за отличную иллюстрацию как именно можно стрельнуть себе в пятку auto.
> Например, в C# есть атавизм в конструкции 'foreach': 'foreach(ItemType item in collection)' неявно приводит элементы 'collection' к типу 'ItemType'.В c# в обоих случаях с типом не будет проблем.
Давай пример, а?
Для детей, выросших на всяких нескучных язычках с выводм типа при копиляции? Ну чтобы не пугать их компиляторозависимыми {инт, инт_малый, инт_большой, инт_оче_большой, инт_с_перламутровыми_пуговицами, инт_от_майкрософтов}.
А может в качестве иллюстрации того, что почти все типы в С так или иначе есть особо интерпретирумое в зависимости от указнного в коде токена, int.
А может просто, по приколу, чтобы число-размер от sizeof(х) было нескучным.
В си всё void* и любые типы это всего-лишь небольшой сахарок компилятора, было бы чем пугать. Мне кажется сомнительной идея перетягивать всё из плюсов, всё равно типизации в языке 0.
Ну, указатели (тупо целое положительное число в hex) уже вводит их в ступор.
И если с функцией, возвращающее это число, они еще более-менее справляются, и даже могут дать команду освободить занятое по нему, то примитивнейшая арифметика с ним, их уже выводит в кататонический ступор.
А ты говоришь чем пугать, чем пугать.
> Мне кажется сомнительной идея перетягивать всё из плюсов,Ну, лишний сахарок, если его немного, редко когда откровенно вредным. Особенно если он сможет в распознавание user-defined типо, вроде struct this_is_very_important_self_documented_struct_type_caption_of_piece_userdata_staff, спрятанного в заголовочнике
> указатели (тупо целое положительное число в hex)Oh, my sweet summer child…
Не пугай кататоника.
Таки шо вы таки говорите...
Оно точно положительное? Есть отрицательный указатель? Может просто hex для удобства, а на самом деле указатель и в двоичной и в десятичной и в восмеричной нотации можно написать?
Адрес в памяти по определению положителен. Указатель помимо адреса может включать содержимое сегментного регистра, например.
Я бы для начала спросил: а является ли указатель числом (адресом)? И ответ: нет, не является. (Но даже и с адресом уже кстати всё может быть не так просто. Например, он может быть не числом, а парой чисел.)
> Я бы для начала спросил: а является ли указатель числом (адресом)? И ответ: нет, не является.ISO/IEC 9899:2017
6.2.5 Types
21 Arithmetic types and pointer types are collectively called scalar types. ...
Не вижу где стандарт формализует, что такое скаляр, но из математики известно, что это одно число.
Указатель это абстракция над адресом, описывает так же и тип адресуемого объекта (в следствии чего инкремент указателя может увеличить адрес на больше чем 1).
> (Но даже и с адресом уже кстати всё может быть не так просто.
> Например, он может быть не числом, а парой чисел.)С адресом всё достаточно просто на физическом уровне, если иметь представление о шине адреса. Пара чисел для динамического ОЗУ (строка + столбец) окажутся просто разными разрядами одного числа. Если есть преобразование в виртуальные адреса, то на уровне приложений его не видно. Процессор может адресовать ячейку парой регистров, о чём я написал (в DOS-е вроде 20 бит был указатель, сегментный регистр + РОН).
> в DOS-е вроде 20 бит был указательНе совсем в DOS (а вообще в реальном режиме) и не совсем 20 (мог быть и 20, и 16, и даже 32 бита, причём не в виде единого числа, а именно в виде пары 16-битных чисел), но это уже несколько анахронизм. А из современного в поисках необычных указателей лучше посмотреть на архитектуру CHERI.
Но главное, что всё это относится только к указателю во время выполнения. А есть ещё время компиляции, когда даже на "обычных" архитектурах указатель не является адресом.
(
> Не вижу где стандарт формализует, что такое скалярДа вот ровно в процитированной вами строчке и формализует: arithmetic types and pointer types. Nothing more, как говорится.
)
>> в DOS-е вроде 20 бит был указатель
> Не совсем в DOS (а вообще в реальном режиме) и не совсем
> 20 (мог быть и 20, и 16, и даже 32 бита,
> причём не в виде единого числа, а именно в виде пары
> 16-битных чисел), но это уже несколько анахронизм.Я так и не понял, зачем повторно вырезаете мои слова про сегментный регистр и регистр общего назначения (РОН) и пишете про два числа. Адрес, по которому процессор читает или пишет, определяется опкодом (полями R/M и SIB) и префиксом смены сегментного регистра, если он есть. В результате декодирования и исполнения команды на шину адреса выставляется одно "число".
>> Не вижу где стандарт формализует, что такое скаляр
> Да вот ровно в процитированной вами строчке и формализует: arithmetic types and
> pointer types. Nothing more, как говорится.Здесь формализован тип указателя. Сказано, что указатель является скаляром, как и целые. Т.е. одно число. Откуда взялось два?
> Адрес, по которому процессор читает или пишет, определяется <...> В
> результате декодирования и исполнения команды на шину адреса выставляется одно "число".Ну надо же, какой умный этот ваш процессор.
>>> Не вижу где стандарт формализует, что такое скаляр
>> Да вот ровно в процитированной вами строчке и формализует: arithmetic types and
>> pointer types. Nothing more, как говорится.
> Сказано, что указатель является скаляром, как и целые.Не знаю, то ли вы переводите неправильно с английского, то ли ещё что, поэтому переведу:
> Arithmetic types and pointer types are collectively called scalar types.
> Арифметические типы и типы указателей вместе называются скалярными типами.Это просто определение "скалярного типа", не больше и не меньше. Ни о каких числах тут речи не идёт.
>> Адрес, по которому процессор читает или пишет, определяется <...> В
>> результате декодирования и исполнения команды на шину адреса выставляется одно "число".
> Ну надо же, какой умный этот ваш процессор.Вы заявляли про два числа. Откуда они взялись?
>>>> Не вижу где стандарт формализует, что такое скаляр
>>> Да вот ровно в процитированной вами строчке и формализует: arithmetic types and
>>> pointer types. Nothing more, как говорится.
>> Сказано, что указатель является скаляром, как и целые.
> Не знаю, то ли вы переводите неправильно с английского, то ли ещё
> что, поэтому переведу:
>> Arithmetic types and pointer types are collectively called scalar types.
>> Арифметические типы и типы указателей вместе называются скалярными типами.
> Это просто определение "скалярного типа", не больше и не меньше. Ни о
> каких числах тут речи не идёт.types - это множественное число.
Ни о каком одном типе тут речи не идёт.
И арифметический тип - скалярный тип.
И указатель - скалярный тип.
Может надо еще и scalaris перевести с латыни? Ступенчатый. В единичной системе счисления осталось записать для наглядности.Далее в том же пункте указаны агрегатные (составные) типы: Array and structure types are
collectively called aggregate types."Два числа" это как раз составной тип.
> Вы заявляли про два числа. Откуда они взялись?В программах на Си для реального режима x86 дальние (far) указатели представлены парой шестнадцатибитных чисел — селектором и смещением.
>> Вы заявляли про два числа. Откуда они взялись?
> В программах на Си для реального режима x86 дальние (far) указатели представлены
> парой шестнадцатибитных чисел — селектором и смещением.Вопрос был, откуда это мнение взято.
Цитирую IA-32 SDM, Vol 1:
1.3.4 Segmented Addressing
...
The following notation is used to specify a byte address within a segment:
Segment-register:Byte-addressFor example, the following segment address identifies the byte at address FF79H in the segment pointed by the DS register:
DS:FF79HТо есть, _адрес_ ячейки записывается парой чисел, подобная форма записи принята в том мануале.
Цитирую Ваше сообщение #277"является ли указатель числом (адресом)? И ответ: нет, не является."
По-вашему, указатель не является адресом, значит к нему "пара чисел" из SDM не применимо.
В стандарте Си указатель назван скаляром. Из чего следует, что "в программах на Си для реального режима x86" одно число (значение указателя) загружается в регистровую пару из селектора и РОНа.
> В программах на Си для реального режима x86 дальние (far) указатели представлены
> парой шестнадцатибитных чисел — селектором и смещением.Интересно насколько вообще то нечто вообще соответствовало каким либо стандартам си.
так адрес в памяти или адрес памяти ?
Адрес ячейки. Ячейка памяти находится в памяти. Русский язык позволяет опускать очевидные из контекста слова, заодно отсеивая башпрограммистов.
> Ну, указатели (тупо целое положительное число в hex) уже вводит их в ступор.Начитаются такого и потом конпелируют только с -O0 потому, что даже -O1 "бажит" их божественный код...
> В си всё void* и любые типы это всего-лишь небольшой сахарок компилятора, было бы чем пугать.В любом языке со статической типизацией типы -- это "всего-лишь небольшой сахарок компилятора". Информация о типах теряется после компиляции, типы не переживают AST.
> всё равно типизации в языке 0.
0 в ассемблере.
> В любом языке со статической типизацией типы -- это "всего-лишь небольшой сахарок компилятора".C++ там есть рантайм инфа о типе для динамического каста.
> Информация о типах теряется после компиляции, типы не переживают AST.Какой-нибудь ubsan очень резко не согласится с тобой. Он очень даже переживает это и прекрасно расскажет в какой переменной с каким типом ты дал маху. Разумеется оверхед на рантайм проверки значений добавится а размер бинаря станет крупнее, за счет хранения вот этих сведений и кода с проверками. Но так можно из сей сделать что-то типа явы или дотнета, если вы это и правда хотели, особенно если asan еще включить :)
>> всё равно типизации в языке 0.
> 0 в ассемблере.И даже там чуть более чем ноль может быть. Скажем можно проверить что константа лезет в регистр, все такое.
Когда в якобы типизированные ЯП вводили подобия auto - иные адепты типизации и параллельно ненавистники недостаточно-типизированного жс с ходу начинали сс.ать кипятком и в три пасти жрать из корыта
Дело, похоже, совсем не в детях. А если бы не хотели их пугать - так не показывали бы лишний раз раст
inttype.h сто лет в обед, а вы до сих пор "платформозависимые" используете?
>auto в CВот и настал тот день, когда я больше не хочу писать на Си. Я долго его ждал, но не мог придумать почему.
Даже не из-за остутствия контроля за границами массивов?
А я не пользуюсь массивами :-р Вообще, убогая структура дынных.
Привет мир продолжит работать без auto, не переживай ты так
формалисты введут обязательное правило использование auto. А так-как у них мозга нет, то и объяснять им бесполезно. Они устали отбиваться от насмешек молодых про застарелость typedef и отсутствие типа для булевой переменной.
Без них ты бы даже коммент не смог написать, потому что любая строка это массив букв
Только лох использует строки-массивы. Самурай юзает связанные письки.
(((((defun opennet(net(open(net()))))))))
Интересно, что некие гендерфлюидные нотки здесь есть, но в целом да.
Флюгик, чуток со скобками ошибся. Но в целом простительно.
<зануда вкл> буквы в букваре <зануда выкл>
можно получать доступ к строке через указатель.
имя массива это указатель на первый элемент.
можно через указатель хранить разреженные строки (символы через один или через два байта - привет интернализация)
строка это тип string
в С это указатель с определенной дистанцией смещения оканчивающийся null-символом.
в C++ это класс с методами в придачу.
в rust это тип с типажами в придачу.Так что не любая, а для Вас это массив.
> А я не пользуюсь массивами :-р Вообще, убогая структура дынных.Блин как же ты пакеты по сети передаешь в портабельном кроссплатформенном виде?
А зачем массивы при передаче пакетов? Структы, указатели на память.. в каком месте массивы?
Вероятно подразумевалось, что массив понятен всем ОС и языкам. Передается он как полезная нагрузка на уровне приложений. Хотя для этого существует маршалинг, потому что передавать надо не только общие типы.
> А зачем массивы при передаче пакетов? Структы, указатели на память..А указатели на память, типа, не массивы? В сях вообще отличие достаточно маргинальное, можно по индексу, можно по указателю. По индексу порой может быть читаемее, особенно если характерным смещениям дать символические имена.
Более того - массив с указанием максимального размера так то помогает статическому анализу и инструментам типа asan/ubsan, сразу видно если лажа вышла. А без этого указания - нет указания ваших намерений и сильно менее понятно, корректно вон то или нет. Одна из тех вещей которые в си сдалали дурно - указатели в довольно большом числе случаев не подлежат полноценному статическому анализу. Из-за отсутствия деклараций намерений кодера, ага. Тяжелые штуки типа asan конечно и такое могут словить зачастую, но это дофига оверхеда, сильное замедление, да и падеж в рантайм хуже чем в компил тайм.
> в каком месте массивы?
В том же что и указатели на память. Память так то сама массив байтов, внезапно. А чтоб красиво, структурировано и на си - это struct, но вот в провод, воздух или файл его портабельно не пошлешь, чтобы это вышло дешево и сердито.
А чем ты пользуешься?
В общем случае графами. В частных - списками и деревьями.
Ну так в графах и деревьях под капотом тоже массив
Лолшто
Посмотрите исходники malloc().
От меня это не зависит. Я там за границы массива не выйду.
Зато можно вызвать mmap() и реализовать граф поверх той памяти, заменив указатели индексами. Получится под капотом массив.
не всегда оправдано.
Остаётся подвал?
Всякие int,long размер которых не определён спецификацией это ни рыба ни мясо. Есть смысл или чётко определять размер (uint32,int32,int64,float32,float64...) или выводить тип автоматически
Поэтому Си и завоевал популярность.
int - наиболее подходящий для аппаратной платформы.
long в два раза длиннее int.разрядность изменяется, а код остается, надо только сравнивать с границами.
если нужно точно, то есть простой способ узнать размер.
> long в два раза длиннее int.Садись, два.
однобайтное целое (англ. tiny int) — 8 бит, -128 ÷ 127;
короткое целое (англ. short int) — 16 бит, −32 768 ÷ 32 767;
длинное целое (англ. long int, также int32) — 32 бита, −2 147 483 648 (−231) ÷ 2 147 483 647 (231−1);
двойное длинное целое (англ. long long int, также large int, big int, int64) — 64 бита, -9 223 372 036 854 775 808 (−263) ÷ 9 223 372 036 854 775 807 (263−1);Википедия. Чтобы быстро. для 32 битной шины.
> Википедия. Чтобы быстро. для 32 битной шины.Небось еще и русская, где это какой-то отсебяша накорябал? А надо было читать стандарты. В стандарте регламентируется только минимальная ширина. Реальная в энной реализации может быть и больше.
Более того - почти весь код уверен что в int лезет минимум 32 бита. Хотя по стандарту сказано лишь про не менее 16. И попытавшись вон там для AVR заказать вот это вот для скорости (по стандарту же ок!) можно нехило лаптем щей откушать - при том что формально это будут баги в коде.
Ни про какие 32-битные или сколько там еще шины в стандартах вообще ничего не сказано. Как впрочем и про допустим стэк и его использование локальными переменными, и прочие типовые допущения которые ниоткуда не следуют.
в Cortex M int и long 32 бита, а long long уже 64
и опять же это компиляторы и задефайнено так, это же программная условность
#include <stdio.h>
void main(){
int a;
long b;
printf("%d %d\n",sizeof(a),sizeof(b));
return;
}вывод: 4 8
4 байта и 8 байт соответственно
Это хреновые способ доказать что-то. Ваша конкретная машина - не все возможности реализации си на той или иной платформе. Ну вон на AVR можно int как 32 бита сделать. А можно и как 16. Оба варианта, кстати, одинаково валидны по стандарту, второй быстрее, толко де-факто много кода non compliant и вести себя будет криво. Хотя формально это баг именно кривого кода удумавшего что int видите ли может быть более 16 битов, чего никто не обещал.
Профессор, когда-то я это знал, а потом основательно забыл. (с) почти ))
Потому что на практике не встречался с этими платформами.
> Потому что на практике не встречался с этими платформами.Ну как бы если мы про стандарты и код, при этом не важно с какими платформами кто встречался. Важно как оно в стандарте определено. И вот с этим на самом деле там довольно так себе, много фривольностей и недоопределенных вещей что ведет к UB.
> Потому что на практике не встречался с этими платформамиНу, с 64-битными Виндой и Линухом-то все встречались. На первой long 32 бит, на второй - 64.
Эпичнее встречи сint a[sizeof WCHAR];
Когда оно работает в Windows с двухбайтным WCHAR, а потом переносят в Linux и оно вроде работает, но в память не всегда помещается.
> int a[sizeof WCHAR];rol, ты мне немного мозг подамажил таким примером )
Но это ещё что! Когда у тебя сетевой протокол завязан на sizeof, начинается веселье в степени N! Сдишь ты такой, никого не трогаешь. И тут коннектится клиент с винды или со смака.
Маршалинг должен быть.
>> int a[sizeof WCHAR];
> rol, ты мне немного мозг подамажил таким примером )Да накосячил с арифметикой. Сейчас не найду ту тему на ЛОРе, массив создавался для задачи типа "посчитать количество каждого возможного символа в тексте" и на Линуксе то ли несколько минут уходил в подкачку, то ли дома работал, а на работе падал.
Что оно?
1. WCHAR в винде определен, а linux нет?
2. wchar_t имеет платформозависимый размер?
> Что оно?В моём сообщении единственная строка с кодом:
int a[sizeof WCHAR];
> 1. WCHAR в винде определен, а linux нет?
"переносят в Linux" означает, что код запускают в Linux, адаптируя, при необходимости.
> 2. wchar_t имеет платформозависимый размер?
"работает, но в память не всегда помещается" является ответом на этот вопрос. Я забыл там 1 << но InuYasha почему-то догадался.
неа, оно так не работает. оно зависит не только от апаратуры но и от ос.
например long:
OS Architecture Size of "long" type
Windows IA-32 4 bytes
Intel® 64 4 bytes
Linux IA-32 4 bytes
Intel® 64 8 bytes
mac OS Intel® 64 8 bytes
>void main()Чо за дичь? Так пишут старые пердуны учившиеся писать 180-90 гг. на каких-то компиляторах под мастдай.
ага, до первого хардкода или ошибки с sizeof()
Это был закос под кроссплатформенность и одновременно упрощение, который в итоге вылился в гигантский гемор. Я тоже пишу целый огромный хэдер только для стандартизации типов. Причём, ровно так как ты и написал. Потому что меня бесят _t для примитивов.
Он нужен чтобы не писать одно и то же и не ошибаться.
Когнитивная нагрузка ниже, читается легче, api и abi не меняет, сплошные преимущества.
auto это очень хорошее ключевое слово, если им правильно пользоваться. Оно позволяет делать код менее прибитым к типам данных и более простым. Только нужно им праивльно пользоваться.Вот, например, писать
auto idx = 0;
не стоит, т.к. это будет int, а не long int, и не unsigned int, и т.д.А писать
auto alice = person;
очень даже правильно, т.к. тип alice будет такой же как у person и можно будет спокойно менять тип person при рефакторинге, не затрагивая эту часть кода. Да и ошибиться с именем структуры тоже не получится, т.к. тут просто auto.
Или тебе нужен был определенный тип alice, а теперь кто-то "порефакторил" код изменив person и у тебя теперь везде потенциальные ошибки, но которые не всплывают на этапе компиляции.
Если нужен прям определенный тип, то там auto ставить, конечно, нельзя. auto это доп возможности, удобные, но как и все в ЯП оно дает много вариантов как выстрелить себе в ногу.
В zig просто выводится тип автоматически, без этих костылей.В принципе auto - это необходимый, к сожалению, костыль в С++.
Если это так, то си перестает быть языком статической типизации.
> Если это так, то си перестает быть языком статической типизации.Веет башпрограммистами автономных операционных систем.
Статическая типизация - это когда тип фиксируется на этапе трансляции.
> А писать
> auto alice = person;
> очень даже правильно, т.к. тип alice будет такой же как у person
> и можно будет спокойно менять тип person при рефакторинге,А потом мы не узнаем случайно что вооооооон там код не умел на самом деле работать с новым вариантом person, но "как живой" благодаря auto?
И нормальные люди для этого делали typedef'ы на какойнибудь person_t который определен как эвона какой struct, например. А при рефакторе ему поля добавить, снести, огрести все матюки компилера на обращение к отсутствюущему полю, например, сразу узнав где баг рефактора. И чего там улучшит auto кто б его знает.
> не затрагивая эту часть кода.
При рефакторе это отличная заявка на залет.
> Да и ошибиться с именем структуры тоже не получится, т.к. тут просто auto.
А зачем ошибаться именем структуры? Завести person_t какой и всегда его везде давать (something_t это такой полуофициальный convention практикуемый многими кодерами для показа что вот это словно именно тип данных а не что-то еще). При этом указание типа может быть лаконичным но несущим в себе инфо о намерениях кодера, в отличие от "auto".
И на вид это выглядит как шанс прострелить пятку лишний раз, сделав код менее анализируемым и спрятав баги, особенно при рефакторе.
> auto alica = person;Это издевательство над оператором присвоения.
А какое значение у person и нужно ли оно в alisa?
Чем typedef не угодил?
Си уже определяет типы неявно? Переписывать учебники, справочники, вики?
Не пользуйся
> На кой auto в С?Тип auto был всегда по умолчанию.
int a; это auto int a;
Или они ушли от статической типизации и auto может быть чем угодно?
у меня gcc v8.3 на auto a; предупредил, что будет считать а целым типом.
> Или они ушли от статической типизации и auto может быть чем угодно?Не ушли но это именно вот тот другой auto, как в новых плюсах.
> у меня gcc v8.3 на auto a; предупредил,
А он разве умел C23? (C2x)
> вот тот другой auto, как в новых плюсах.Значит auto это то что может реализовать компилятор, а не то что хочет программист.
На вопрос почему, будет ответ я так вижу. Вы же не определили четко.
А что, в Си запретили использование макросов? Вполне может там оказаться удобно пользоваться `auto`:#define SWAP(a,b) do { auto t = a; a = b; b = t; } while(0)
> #define SWAP(a,b) do { auto t = a; a = b; b
> = t; } while(0)
Смотрите дети как себе метко в пятки стрелять, да не просто а в прыжке, с заподвыподвертом, левой рукой в правую. С перезарядкой арбалета на лету. Или отличный пример как делать не надо.Хинт: в этом макро радикально не хватает как минимум скобочек. Вы когда его задефайнили думали лишь про 1 юзкейс но caller может делать дохрена того о чем вы не подумали.
Как вам например SWAP(x++, ++y)? А если SWAP(++x, y++)? Это одно и то же или нет? :) А может, там выражение какое? И вон то макро вам такие интересные side effects посчтитает...
Более того, а что если у a и b тип разный? У том чудо макросе это не проверяется вообще никак, и есть шансы выпилить варнинг о том что вы толкаете слона в клетку для канарейки.
А то что вы хотели на самом деле _Generic называется, и таки начиная с C11 - есть. При том там это можно более культурно оформить. Во первых без залета на непонятки в вон тех случаях, во вторых можно более ограниченно указать какие типы эта штука может стрескать. А с вот таким макро вы соберете сильно больше багов чем могли бы себе представть. И так вполне реально вулн в коде повесить, хотя на вид все ЗБС.
> Как вам например SWAP(x++, ++y)? А если SWAP(++x, y++)?Не надо так писать. Видно же, что это макрос.
> Не надо так писать. Видно же, что это макрос.Иногда очень соблазнительно воткнуть туда вот именно некое выражение. Из соображений лаконичного, читаемого, простого в восприятии кода. Потому что если вместо этого сделать костыль из нескольких малоочевидных строк более удачным решением это тоже не станет.
Если макрос писал не полный дилетант, макро будет вести себя приличнее, хоть и ценой разбавки макроса скобками. А, да, знаете, чтобы багов в коде было меньше, код должен быть лаконичным, выразительным и простым в понимании. И макросы имеет смысл использовать разве что для этого. В плане допустим оптимизации кода они давно сравнялись с функциями. Можно даже анти-оптимизацию получить - технологии типа LTO легко могут заинлайнить небольшой кусок функции а не ее всю, упростив и ускорив все в цать раз. С макро это получается значительно хуже.
Итого: показан пример как испортить жизнь оптимизеру и влепить неочевидных багов.
>> Не надо так писать. Видно же, что это макрос.
> Иногда очень соблазнительно воткнуть туда вот именно некое выражение."Я захотел нарушить конвенцию, но виноват вон тот".
> "Я захотел нарушить конвенцию, но виноват вон тот".В реально требовательных штуках, типа MISRA, насколько я помню, конвенция такова что на использование макро накладываются крайне жесткие ограничения, так что вон то использование (function-like macro) будет под запретом. Во избежание вот этого вот всего вообще крайне радикальным методом.
А ваша конвенция - вообще чья и как сформулирована? Она задекларена в каком-то стандарте или устоявшемся гайдлайне? У реально критичных предпочитают совсем не связываться с макро по возможности. Менее радикальные, которые хотят более читаемый код но не баги, обучаются обкладывать козлаW матом^W^W макросы скобками.
И таки если вместо 1 строки (т.е. макро с 2 выражениями) станет 3 - код станет более рыхлым и это тоже испортит его восприятие. Может прибавиться ситуаций "функция не умещается на экран", что тоже баги вызовет. А, да, у тех кому критично есть довольно жесткие лимиты на размеры и сложность функций, так что +3 строки тоже так то трабла.
Есть еще вызовы функций с side effects но там можно откушать даже в аргументах функции и тут уж програмер должен голову задействовать.
С другой стороны для себя я все же позволил некое более широкое использование макросов. Даже для проверок некоторых вещей компилтайм, как это делать можно подсмотреть в линукскернеле. Компилтайм предвычисления и проверки все же прикольны и ничего не стоят в рантайме.
> Хинт: в этом макро радикально не хватает как минимум скобочекэто макро было иллюстративным и только.
> Как вам например SWAP(x++, ++y)?
Никак. Написавший такие аргументы в таком макро -- идиот, лечить бесполезно. Выстрелить себе в любую часть тела на Си не было проблемой вообще никогда. Макросы от того и пишут большими буквами, чтобы те, кто ими пользуются понимали "хрупкость" и осознавали возможности сайд-эффектов.
> А то что вы хотели на самом деле _Generic называется, и таки начиная с C11 - есть.
Без генерика приведённый вариант обмена значений будет работать даже с любой стркутурой, а как он будет с генериком -- вопрос интересный. Не всё ограничивается только вариантами целых чисел.
> Смотрите дети ...
Проецирование своих комплексов наружу? Ну-ну
> это макро было иллюстративным и только.Зачем подавать пример как делать не надо, особенно если есть куда менее стремные генерики?
> Никак. Написавший такие аргументы в таком макро -- идиот, лечить бесполезно.
Иногда тем не менее для лаконичности кода удобно выражение воткнуть в аргумент. Отдельные 2 строки для чего-то в этом духе ведет
> Выстрелить себе в любую часть тела на Си не было проблемой вообще никогда.
Не значит что надо таскать заряженный пистолет снятый с предохранителя в повседневной жизни, пятки не одобряют такой маневр.
> Макросы от того и пишут большими буквами, чтобы те, кто ими пользуются
> понимали "хрупкость" и осознавали возможности сайд-эффектов.Их можно сделать значительно менее хрупкими воткнув пару скобок. Да и вон то лучше наверное функцией делать. По перфомансу и коду врядли проиграет.
>> А то что вы хотели на самом деле _Generic называется, и таки начиная с C11 - есть.
> Без генерика приведённый вариант обмена значений будет работать даже с любой стркутурой,Да. Но это тоже некоторые грабли. Структуры могут быть довольно большие (в этом случае, разумеется, место для них может выделяться динамичеси). А то что вы хотели аллоцировать на автомате темпарь вон того размера - это еще вопрос! В стеке же награда за нехватку памяти это сразу крах. Без возможности что-то сделать. Да, в struct можно и массивы вогнать и проч. И это тот случай когда вы таки можете скормить сям массив именно by-value, и вот вообще совсем не факт что вы именно ЭТО хотели. Потому что это конечно сработает но перфоманс всего этого будет хуже чем у жабы с дотнетом если массив большой.
В случае struct'ов и желания их свапнуть это тот случай когда возможно вы хотели на самом деле указатели на struct и свапнуть именно их. А у вас это скорее всего нечто типа memcpy будет (да, компилер может сам его или что-то подобное вызвать в случае struct). Это даже по своему удобно когда массивы можно лихо приравнивать, но лучше явно понимать смысл этого действа, особеенно если массив не особо маленький.
> а как он будет с генериком -- вопрос интересный. Не всё
> ограничивается только вариантами целых чисел.На самом деле интересная тема, в вашем спиче что-то есть.
> Проецирование своих комплексов наружу? Ну-ну
Это проецирование коллективного разума вон тех мощных кодеров на ваши бренные головы.
>> разрешение использования constexpr и auto при определении объектов
> На кой auto в C? В C++ он нужен из-за монструозных template'тов.По ссылке:
#define dataCondStoreTG(P, E, D) \
do { \
auto* _pr_p = (P); \
auto _pr_expected = (E); \
auto _pr_desired = (D); \
bool _pr_c; \
do { \
mtx_lock(&_pr_p->mtx); \
_pr_c = (_pr_p->data == _pr_expected); \
if (_pr_c) _pr_p->data = _pr_desired; \
mtx_unlock(&_pr_p->mtx); \
} while(!_pr_c); \
} while (false)Без auto тип аргумента приходится передавать аргументом макроса.
> В C++ он нужен из-за монструозных template'тов.Говорите прямо - запутались. auto как палочка выручалочка. Что получится не важно, главное скомпилировать.
> На кой auto в C? В C++ он нужен из-за монструозных template'тов.Трольнул, круасафчег ! Все отписавшиеся выше не знают не то что сей, их к компу мамка подпускать не должна пока к&r на зубок не выучат.
> bool, false и trueКто лучше знает, это получается, что в новом стандарте Си появился полноценный булевый тип? Что мешало добавить его раньше?
Не особо нужен. char и значений 0, 1 всегда хватало.
Си, в отличие от C++ - это не о абстракциях.
Конкретно с char(byte) ты бахнешься на процах, которые требуют выравнивания при обращении к памяти.
Ну или займёшь 64-битное слово на каждый буль.
Плохому танцору известно что мешает. В 2023 жаловатся на вышеперечисленное просто смешно.
Можно юнионом укладывать в чар 8 булей. А выравнивание -- это проблема компилятора.
Чо... хранить логические переменные в одном бите? Ну можно, конечно, но изврат какой-то.
погугли, что такое программирование, а потом про битовые поля
И тут аноны откроют для себя флаги. )
они всегда были затратные если только одно битовое поле. Хард программирование исключается из утверждения.
Нет, лучше в 64. Параллельно запивая смузи.Обычный приём, который преподаётся в старших классах при изучении страктов и юнионов.
Мало в каких школах дают Сишечку. В основном дают Питон сейчас. Си скорее на первом курсе изучают.
Верно, но это уже неустранимые проблемы нынешней системы образования, обсуждать которые -- значит скатиться в политоту.Так-то по-нормальному в младших классах должны быть основы информатики -- алгоритмизация, простейшая формальная логика с соответствующими задачами. В средних классах -- Питон, в старших -- Джава/Си/Го/Хруст на выбор и основы системного администрирования.
В младших - Assembler, в средней школе - Brainfuck, в старших - Rust!
По выпуску устраивать в M$ архитекторами ядра.
Молодец, теперь попробуй осуществить свой педагогический эксперимент, начав с собственных детей. Если, конечно, успел настрогать.
> Можно юнионом укладывать в чар 8 булей.Лучше struct'ом. Проблема однако в том что это хотя и сэкономит RAM под були, сгенерит лишний код на RMW этого счастья. Результат как правило медленнее работает и жирнее по коду, так что особого профита с этого лайфхака не наступает.
Код будет жирнее -- ну может быть, от компилятора и опций зависит. Что будет медленнее -- не верю.В крайнем случае можнно просто создать переменную типа int8_t, и для манипуляций с конкретным битом использовать операции по маске. И в /** камментах **/ не забыть написать, для чего используется каждый бит :)
> Код будет жирнее -- ну может быть, от компилятора и опций зависит.Чтобы хранить 8 булей в 1 байте... внезапно, выставить бит в 1 более не немедленное присвоение переменной значения, типа mov r0, #1, а уже вполне себе RMW байта (или что там) - надо прочитать текущее значение, пропатчить, выставив в 1 нужный бит и сохранить назад. И обращений в память 2. Если неаккуратно делать можно еще и на гонки нарваться, если не байт а что-то крупнее и доступ не атомарный был.
> Что будет медленнее -- не верю.
А таки - может. И бывает.
> В крайнем случае можнно просто создать переменную типа int8_t,
> и для манипуляций с конкретным битом использовать операции по маске.Так вы и тут на RMW пролетаете, вы ж не можете просто заассайнить ему нужное, еще и предыдущее сохранять надо! Иначе упакованые флаги отправятся нафиг.
> **/ не забыть написать, для чего используется каждый бит :)
Я пробовал и так и сяк. В 1м случае компилер врезает RMW, автоматически, в 2м случае еще и самому мануально надо, совсем уж хрень, возни больше, результат тот же (правда, u8 проще портабельно слать в IO/file/etc vs struct). А если bool как инт оформлен, RMW не надо, ведь там 1 бит, он сразу известен. Не надо чтение старого значения и маски, внезапно. Классический разгон скорости выполнения за счет большего потребления RAM.
Серьёзно, char в качестве bool? Чтобы strict aliasing многого о себе не возомнил? Типичный такой эффективный Си
Поэтому в добром Си, на котором писали ОС, и не было этого типа. Была логика: 0 и всё остальное.
И можно выбирать для хранения выровненный тип.
Но пришло другое поколение и появился bool и auto (
то чувство, когда маленькие дети не знают про stdbool.h, но рассказывают всем о том, как всегда было
[ ] Деды (Ритчи и Керниган) не пользовались, и тебе не надо.
[ ] Не писали с валио-трулио, неча и начинать.
[ ] Нуля и единицы хватит всем.
[ ] Зачем тебе тип, который всего 1 бит, если быстрее юзать выровненные по размеру регистра целые?
[ ] А для поля таких флажков тем более выровненные по регистру слово/полуслово, да в десятичном виде!
[ ] Так быстрее же!
[ ] Зачем терять 7 бит на мусор, когда нужен всего 1?
[ ] Читаемый код должен быть тому, кто сидит около регистров, а не мимо-пацану с тремя классами алгола церковно-фортановой школы!-----
Выбирай любой набор причин.
А зачем он нужен? По-моему 0/1, проще чем false/true.
Разная смысловая нагрузка (типы они для людей): получается ты своим болевым типом можешь делать тоже что с целым числом (складывать, умножать и и.п.) - зачем это нужно? Ты можешь возразить, что можно просто так не делать, но тогда мы перекладываем дополнительные поверки на погромите, а ему и так есть над чем думать.
0/что_угодно_целое
for(int i=10;i;i--){
//тело
}
Лучше так не писать
> А зачем он нужен? По-моему 0/1, проще чем false/true.Например:
uint8_t var1 = 256;
if (var1) do_something(); // Хоть var1 не ноль на вид, там 0 и сюда не попадем!
bool var1 = 256;
if (var1) do_something(); // А вот тут будет вызвано (var1 == true)Секрет в том false залекларен как 0, true как 1, а все что больше обрубается при матеметике до 1. И в принципе можно при статическом анализе варнинги кидать если там более 1. Меньше места для прострела пяток в целом. Просто более специфицированный под задачу begavior, более уместный.
>>uint8_t var1 = 256На подобное заведомое переполнение gcc ругается.
И когда из большего типа в меньше без приведения типа присваивают, тоже ругается.Про bool - верно.
> На подобное заведомое переполнение gcc ругаетсяИ это если повезёт. Недавно искал проблему в коде, где
> printf("%d == %d (%d)\n", a, b, a == b);
выводило то ли "9 == 11 (1)", то ли "11 == 11 (0)" просто из-за такого вот неопределённого поведения где-то рядом в коде, после которого компиятор получил карт-бланш на любые извращения в целях копеечной оптимизации.
> На подобное заведомое переполнение gcc ругается.Это был простейший пример. В реальном коде будет нечто ближе к:
uint8_t var1 = 255;
...
var1++;
if (var1) ... // Ну и вот кто тут про ноль из-за mod(2^8) math подумает? :)
...и на это ругаться уже не будет в общем случае.> И когда из большего типа в меньше без приведения типа присваивают, тоже ругается.
Если кто храбрый -Wconversion ему в руки, узнаете много нового о своем коде и его (без)глючности и (без)опасности в плане работы с целыми числами.
> Про bool - верно.
Его все же специально сделали для логических выражовываний, с inеeger'ами это не сколько более стремное занятие.
> Если кто храбрый -Wconversion ему в руки,Да, 90% бестолковых предупреждений, но для своего кода, так использую, иногда помогает же.
Но оно не отлавливает опечатки с присвоеним разных типов, и если типы совпадают по размеру, то по мнению компилятора сойдёт и так.
> Да, 90% бестолковых предупреждений,Вообще-то вполне толковых, а то что часто прокатывает и так - на самом деле без гарантий и благодаря вот этой штуке дурных багов математики отловлено немеряно. А где ну вот очень надо что-то странное - явно кастовать, не халявить. Хотя система типов в си все же весьма специфичная, и вон то лишь хайлайтит это дело, не более.
> но для своего кода, так использую, иногда помогает же.
Сильно повышает качество кода. И я про него узнал от Ian Colett - автора LZ4, в его бложике о том как писать код качественнее и надежнее.
> и если типы совпадают по размеру, то по мнению компилятора сойдёт и так.
Это какой-то совсем нишевой случай. Для pointer vs integer вопли есть, struct'ы логично юзать через typedef'ы и так чужой структ совсем скормить без явного желания нереально.
>> Да, 90% бестолковых предупреждений,
> Вообще-то вполне толковых,Вообще то, в первую очередь интересует отлов ошибочного присваивания не тому типу, хоть и того размера, а не приведения типов. Хотя в коде предназначенном для сборки для 32 и 64 битных систем, грабли найдутся и там.
Но, поскольку лучше по максимуму отловить проблемы на стадии компиляции, а не из багрепортов, то мне более приемлимы "бестолковые" предупреждения. И исходник считается вменяемым, если нет предупреждений при включении практически всех опций, кроме Wpedantic.
> Вообще то, в первую очередь интересует отлов ошибочного присваивания не тому типу,
> хоть и того размера, а не приведения типов.А что это за ситуации вообще? Мной это не распознается как какая-то типовая проблема, чтобы "в первую очередь" волновало. Нельзя ли конкретных примеров как, где и почему это является заметной проблемой?
> Хотя в коде предназначенном для сборки для 32 и 64 битных систем,
> грабли найдутся и там.В нормально написаном портабельном коде там вообще грабель не должно быть. Для себя я предпочитаю C99 и конкретные размеры типов, для точно определенного диапазона значений, так что платформа либо предоставляет мне ЭТО либо "out of luck" (с 99го года почти четверть века прошла).
> Но, поскольку лучше по максимуму отловить проблемы на стадии компиляции, а не
> из багрепортов, то мне более приемлимы "бестолковые" предупреждения.Я даже false alarm статических анализаторов затыкаю. Потому что не прочь поразвлечься всяким микроконтроллерным и управляющим и последнее что я хочу это баги в таких применениях. В этом месте параноидальные варнинги и статический анализ очень хорошая идея.
> И исходник считается вменяемым, если нет предупреждений при включении
> практически всех опций, кроме Wpedantic.Я переживаю как минимум Wall, Wpedaitic, Wconverson и как минимум cppcheck еще. Если кто-то из них недоволен, это еще не релизное качество.
>> Вообще то, в первую очередь интересует отлов ошибочного присваивания не тому типу,Это считай руко%опство в проектах которые пишут несколько человек, и особенно в разное время, и оно плохо плохо обнаружимо, и может даже вполне работать.. пока не тронешь.
> В нормально написаном портабельном коде там вообще грабель не должно быть.
Чужой код в принципе не бывает нормальным, и особенно тот в котором попросили исправить "мелочи" или доработать. Шутка, но с долей правды.
> Это считай руко%опство в проектах которые пишут несколько человек, и особенно в
> разное время, и оно плохо плохо обнаружимо, и может даже вполне
> работать.. пока не тронешь.Мне пример этого интересен, как бы это могло выглядеть. Потому что сходу баг такого типа не припоминается особо. И хотелось бы понять как и почему это образуется и (если это выглядит правдоподобно) как этого можно было бы избегать.
> Чужой код в принципе не бывает нормальным, и особенно тот в котором
> попросили исправить "мелочи" или доработать. Шутка, но с долей правды.На самом деле чужой код бывает очень разным. От г-на до мегарулеза. При том иногда все и сразу, за некоторый код хочется наградить кодера медалью и расстрелять.
Если использовать uint8_t как bool, то производительность упадёт. Лучше использовать uint32_t - производительность выше.
> Лучше использовать uint32_t - производительность вышеА если использовать 64 байта и выравнивать на 64 байта, то автоматом избавимся ещё и от проблем с мультипроцессорностью из-за доступа нескольких ядер к одной строке кеша.
А что там такое может храниться может на практике, что разные ядра лезут в смежные ячейки?
> Если использовать uint8_t как bool, то производительность упадёт. Лучше использовать uint32_t
> - производительность выше.Для intel 32bit - да. А других архитектурах может быть быстрее.
На x86_64 операции с uint32_t будут быстрее, чем с uint8_t и uint16_t.
а на AVR?
> а на AVR?Вы сами догадываетсь.
На Cortex и Risc-v 32bit 8/16 битный bool быстрее 32х битного.
> На x86_64 операции с uint32_t будут быстрее, чем с uint8_t и uint16_t.Когда будут и кто обещал? Пока операции с регистрами занимают одинаковое количество тактов (uint16_t не беру в расчёт, это почти не используют), а чтение из памяти в сумме быстрее для компактных данных.
> Когда будут и кто обещал?См. документацию по ассемблеру x86_64.
>> Когда будут и кто обещал?
> См. документацию по ассемблеру x86_64.Зачем я буду смотреть всякую чепуху, какую Вы и процитировать стесняетесь? Я смотрю 64-ia-32-architectures-optimization-manual.pdf (см. цитату в №222), AMD_Athlon_Processor_x86_Code_Optimization_Guide.pdf и Software Optimization Guide for AMD Family 17h Processors-55723_3_01_0.zip
>> Если использовать uint8_t как bool, то производительность упадёт. Лучше использовать uint32_t
>> - производительность выше.
> Для intel 32bit - да. А других архитектурах может быть быстрее.Из относительно современных нашёл такое только для Atom (не путать с Silvermont и более новыми - 45 nm Intel Atom processors introduced Intel Atom microarchitecture. The same microarchitecture also used in 32 nm Intel Atom processor)
D.3.3.5
Parameter Passing
Due to the limited situations of load-to-store forwarding support in Intel Atom microarchitecture, param-
eter passing via the stack places restrictions on optimal usage by the callee function. For example, “bool”
and “char” data usually are pushed onto the stack as 32-bit data, a callee function that reads “bool” or
“char” data off the stack will face store-forwarding delay and causing the memory operation to be re-
issued.
Compiler should recognize this limitation and generate prolog for callee function to read 32-bit data
instead of smaller sizes.Assembly/Compiler Coding Rule 18. (MH impact, M generality) For Intel Atom processors, “bool”
and “char” value should be passed onto and read off the stack as 32-bit data.
> Если использовать uint8_t как bool, то производительность упадёт. Лучше использовать uint32_t
> - производительность выше.Вот прям так универсально? Ну попробуйте свой совет на AVR. И получите пролет по скорости в разы. Компилеру виднее как bool оформить потребно на его платформе в вон тех гарантиях. Переумничать компилер? Вы скорее пятки себе прострелите с таким уровнем знаний.
"uint8_t var1 = 256;"И в этом весь C. Сделать для быстрого косособачинга кривую функцию компилятора (обрезание типов молча) и гору ad-hoc библиотечных функций. Заявить этот набор "стандартом". 30 лет со всем этим мяснить, порождая горы прог и утилит, дырявых в самых неожиданных местах. Через 30 лет начать пытаться сделать из этого Паскаль с C-синтаксисом.
> И в этом весь C. Сделать для быстрого косособачинга кривую функцию компилятора
> (обрезание типов молча) и гору ad-hoc библиотечных функций. Заявить этот набор
> "стандартом". 30 лет со всем этим мяснить, порождая горы прог и
> утилит, дырявых в самых неожиданных местах. Через 30 лет начать пытаться
> сделать из этого Паскаль с C-синтаксисом.А теперь ещё раз и по-русски.
дитё порвало ( | ) :-D
сию конструкцию засунуть в компилятор и понять что не собеётся, ума (предсказуемо) - не хватило :)
И соберётся и запустится. Эффект окажется для некоторых неожиданным. Особенно для перепутавших компилятор с линкером.
> сию конструкцию засунуть в компилятор и понять что не собеётся, ума (предсказуемо)
> - не хватило :)Соберется, но в современных компилерах warning выдаст.
> И в этом весь C. Сделать для быстрого косособачинга кривую функцию компилятора
> (обрезание типов молча)Не угадал, де факто там варнинг в современных компилерах будет. Но как утрированый пример сойдет, влом было кодить обман варнинга в утрированом примере, извини.
> утилит, дырявых в самых неожиданных местах. Через 30 лет начать пытаться
> сделать из этого Паскаль с C-синтаксисом.Где там и чего от паскаля вообще? Это я как прогавший на паскале спрашиваю.
Он уже был в С11 как _Bool, сейчас stdbool.h решили деприкейтнуть.Сам bool вообще штука так себе, например в структурах DoP лучше не добавлять его. Он по-сути нужен только при касте, т.к каст у int другой.
Он и вон тем stdbool'ом был как bool вывешен (как typedef вроде). То что для нормального була вместо левоватого _Bool надо добавочный хидер вообще смотрелось странновато как по мне.
Целочисленные типы сей как булеан довольно опасная штука, они врапаются по основанию 2, как минимум unsigned - и можно внезапно получить инверсную логику.Для signed превыщение min/max это по сути UB, хотя в 23 и последних плюсах вроде собирались регламентировать только 1 формат представления (twos complement) и тогда это уже "defined behavior" будет. Но в более ранних не указано как знак и знаковые хранить и там возможно нескллько вариантов. Формально валидных и - с разным поведением при переполнении, потому и UB.
> Для signed превыщение min/max это по сути UB, хотя в 23 и последних плюсах вроде собирались регламентировать только 1 формат представленияНу да, оставили только two's complement
> и тогда это уже "defined behavior" будет
Нет, не будет. Поскольку возможность переполнения мешает ещё и оптимизатору
> Ну да, оставили только two's complementВидимо дотумкало что столько UB сколько там есть - не рулит совершенно.
>> и тогда это уже "defined behavior" будет
> Нет, не будет. Поскольку возможность переполнения мешает ещё и оптимизаторуЕсли остался только 1 формат хранения - по идее его wrap конкретно определен уже. А оптимизатор не имеет права нарушать иллюзии прописаные в стандарте. Хотя я и не смотрел этот кусок на тему гарантий, стандарт еще не вышел даже вроде?!
> по идее его wrap конкретно определен ужеНу, допустим. Дело же не в нём. Проблема в том, что оптимизатор может заложиться на тот факт, что число не переполняется, а значит и можно выпилить явные/неявные ветки кода, ожидающие переполнения
Оптимизатор видит, что x == 10 и x только инкрементится — всё, ветку if (x == 9) {} можно просто выкинуть
У нас не механизм переполнения оказывает влияние на производительность, а само наличие такой гарантии
> А оптимизатор не имеет права нарушать иллюзии прописаные в стандарте
Так стандарт не позволяет переполнения, а значит и оптимизатор, выкидывающий лишние ветки, тоже ничего не нарушает — он заложился на отсутствие гарантий. Из-за этого, например, код с беззнаковыми может быть местами медленнее
> стандарт еще не вышел даже вроде?!
Стандарт — нет, но его черновик можно посмотреть или на гитхабе комитета в виде исходников, или собранный на eel.is/c++draft
> Ну, допустим. Дело же не в нём.Компилер обязан поддерживать заявленную абстракцию. В том числе и в оптимизере, в виде как если бы его не было. Если оптимизированный код отличается в поведении и он не уповал на UB, это уже будет баг оптимизатора тогда. На самом деле конечно больше баг стандартов абы как писаных, но, вот, хоть немного выправлять начинают это безобразие.
> Проблема в том, что оптимизатор может заложиться на тот факт, что число
> не переполняется, а значит и можно выпилить явные/неявные ветки кода,
> ожидающие переполненияДля unsigned это вообще оптимизация - заложиться в коде на размер чтобы mod 2^N вообще нахаляву получить. Актуально криптоалгоритмам всяким и тому подобному. Для signed это не практиковалось из-за UB.
> Оптимизатор видит, что x == 10 и x только инкрементится — всё,
> ветку if (x == 9) {} можно просто выкинутьЭто катит только если он может _доказать_ это. И даже так он может лопухнуться, потому что видит он все-таки не все. Скажем IRQ - оптимизер не видит, однако его вышибают в пользу другого кода. Для подобных случаев есть volatile. В чем то похожие проблемы есть в многопоточных конструкциях.
> У нас не механизм переполнения оказывает влияние на производительность, а само
> наличие такой гарантииА вот это большой вопрос. Оптимизер может в дофига случаев пруфнуть те или иные граничные условия и вообще например обрубить функцию с кучей switch ... case до пары команд, доказав что оно получает только 1, 5 и 7 на вход по вообще всей программе. LTO в этом очень крут.
> Так стандарт не позволяет переполнения, а значит и оптимизатор, выкидывающий лишние ветки,
> тоже ничего не нарушает — он заложился на отсутствие гарантий. Из-за
> этого, например, код с беззнаковыми может быть местами медленнееЭто было актуально ДО C23 но актуально ли для него - а вот это интересно.
> Стандарт — нет, но его черновик можно посмотреть или на гитхабе комитета
> в виде исходников, или собранный на eel.is/c++draftЗачем мне драфт на C++ если мы про си?
Тип и раньше был, как минимум с C99, только надо было включать stdbool.h. А если без включения, то был _Bool.
макаки написали, макаки убежали, им бесполезно доказывать, они не программисты
>> bool, false и true
> Кто лучше знает, это получается, что в новом стандарте Си появился полноценный
> булевый тип? Что мешало добавить его раньше?Когда язык проектировали как замену ассемблеру, тогда булевый тип хранился во флагах процессора. Тогда идея заставить компилятор тратить под один бит целый байт выглядела дикой - это оставляли на совесть программисту.
несчастливый номер, пожалуй пропущу эту версию анбора конпиляторов
А в Китае число 4 боятся, как огня, хотя ничего такого в нём нет.
> А в Китае число 4 боятся, как огня, хотя ничего такого в
> нём нет.Почему нет, если читается как "смерть"? Но, я думаю, в целом, в китае большой прогресс в истреблении мракобесия, особенно, по сравнению религиозным фанатизмом соседей. Вот что трудовые лагеря животворящие делают!
>в китае большой прогресс в истреблении мракобесияУничтожение древних текстов и старых храмов, которые могли бы правдиво рассказать о древней истории и заместо старинных зданий клепать новоделы это не истребление мракобесия.
Дану, стремное какое-то. Тоже начну бояться.
Пятёрка конечно лучше четвёрки, но тройка еще хуже. Самое счастливое число это 5.
13. 1 + 3 = 4. Вуаля! (тут чинацйы собрали кирпичей на новую Стену)
> несчастливый номерБэкхенд на расте как раз добавили, плохой знак
> несчастливый номер, пожалуй пропущу эту версию анбора конпиляторовПовеяло мракобесием автономной ОС, у которой уже пять штук 12-х версий.
Если понимать, откуда оно пошло и что такое дюжина - так как раз 12-й Дом - Дом Смерти.
дюжина - это 12 костяшек на 4 пальцах одной руки, которые считали пятым(большим)
Только костяшками считали не сами костяшки, а что-то из жизни. Например, 4 времени года по 3 месяца.
у Cisco IOS'a не было 13 версии,была 12 а потом 15. Циско - молодцы.
У них и этажей нет 13-х, что с них взять, если это давняя традиция. Вон те в автономной ОС умело устроили карго-культ своему господину.
Хм. А я всегда думал, что это про Иисуса -- если вместе соберутся 13 человек, то 1 в течении года умрет. Что даже чисто теоретически вполне вероятно.
Наша Эра началась с т.н. Великого соединения Юпитера и Сатурна в знаке Рыб в момент зимнего солнцестояния. И кстати в 2020-м она таким же соединением в Козероге закончилась. Наберите в поисковике "Эра Водолея" - вот примеры, как астролухи путают знаки Зодиака и созвездия, строя из себя знатоков и паря мозг охлосу.
> несчастливый номер, пожалуй пропущу эту версию анбора конпиляторовнормально. 2.6 было топовое ядро. 26 = 13*2.
Как там netcdf - компилируется ??
А не должен, что ли?
Даааа, такие популярные языки добавлены (не только в 13), Модула и Фортран…. И не видно что кто-то ненавидит эти старенькие плохонькие языки . А вот Паскаль ненавидят, и там и тут лезут уроды с критикой . Хотя Паскаль мощнее и лучше и проще и изящнее Модулы и Фортрана. Я на нем CudaText пишу. Гислер ТоталКомандер пишет.
Fortran там сто лет как.
Паскаль - отличный язык. По сути, это тот же Си, только с более понятным новичкам синтаксисом - типа, begin/end вместо фигурных скобок. Я когда-то с Паскаля без особых усилий на Си перешёл - там всё точно так же, только запись короче)
Ну да, с удобным ср@чем из всех всех всех переменных функции в её начале.
По мне, так подобные анахронизмы даже хуже чем излишняя многословность, ибо плодит трудно обнаружимые ошибки использования переменных.Не знаю как сейчас, но когда то в Делфи были коварные проблемы с многопоточным кодом на многоядерных процессорах, что у нас и стало одним из гвоздей в крышку его гроба.
Может быть, сейчас и исправили, не знаю, но поезд ушёл.А из хорошего помню, по сравнению с Си, более удобная проверка типов, простые var параметры функций, оператор with.
По сравнению с C++, был существенно ПРОЩЕ для НАЧАЛЬНОГО обучения программирования, то есть как одного из первых языков.
>Ну да, с удобным ср@чем из всех всех всех переменных функции в её начале.1)Однопроходный компилятор - наше все.
2) А как чудно решается эта проблема в фортране ...
Переменные в начале логического блока тоже перевариваются однопроходным компилятором, и практически без усложнения компилятора.Это просто древний архаизм, который по недосмотру и стечению обстоятельств не исправили вовремя.
Сейчас в embarcadero это и подобные деревянности исправлены, но уже не актуально.
>>Ну да, с удобным ср@чем из всех всех всех переменных функции в её начале.
> 1)Однопроходный компилятор - наше все.В любом случае переменная объявляется до использования.
Вам изобрели компьютеры чтобы не быть ограниченными одним проходом - нет, хотят г-но жрать.
> плодит трудно обнаружимые ошибки использования переменныхНаоборот уменьшает. И все знают где в тексте статически определены все переменные.
>> плодит трудно обнаружимые ошибки использования переменных
> Наоборот уменьшает. И все знают где в тексте статически определены все переменные.Знают, что определены где то там, вдалеке, но не где используются.
А вот их использование, и особенно неправильное, очень плохо обнаружимо, в чём и проблема. И компилятор тут и пол-warning'a не выдаст.А вобще, это "дурной стиль" ;)
> Наоборот уменьшает. И все знают где в тексте статически определены все переменные.С другой стороны, переменные для циклов типа for (uint8_t i = 0; i < 10; i++) и элегантно и прозрачно хинтит оптимизеру область использования переменной, и позволяет не захламлять сюжетно важный блок с описанием переменных aux сущностями нужными на 1 этот цикл и более - нигде.
> Паскаль - отличный язык. По сути, это тот же Си, только с
> более понятным новичкам синтаксисом -Ну вот для обучения он отличный. Для программирования реальных проектов мерзость занудная.
> типа, begin/end вместо фигурных скобок.
И всего в 3 и 5 раз больше букв набирать для одного результата. И не надо про автокомплит, он с 1 буквы или не сработает или будет дико глюкать, разве что хоткеи какие но визуальное загромождение и раздувание файлов никуда не денется. А в большом проекта даже и чтение файлов и их парсинг может стать аргументом.
> Я когда-то с Паскаля без особых усилий на Си перешёл - там
> всё точно так же, только запись короче)Ну да. И не пытается постоянно охранять от прострела пяток. По поводу чего код быстрее и эффективнее и можно сделать что задумал а не бороться с компилером. Но это как с мощным инструментом - при криворукости и глупости можно покалечиться.
Днищенский язык. Вы только вдумайтесь, в Паскале длина массива и интервал индексов - это составные части типа. Невозможно в одну функцию или процедуру передавать массивы разной длины, так как они имеют разные типы.type vector1 = array [1..25] of real;
type vector2 = array [2..26] of real;var
vec1: vector1;
vec2: vector2;
> Днищенский язык. Вы только вдумайтесь, в Паскале длина массива и интервал индексов - это составные части типаЭто отличная вещь под названием строгая типизация. Ты еще Аду не видел.
Проблема в том, что ты привык к убогим языкам.
> Невозможно в одну функцию или процедуру передавать массивы разной длины, так как они имеют разные типы.
Ну вообще-то можно:
> Днищенский язык. Вы только вдумайтесь, в Паскале длина массива и интервал индексов - это составные части типа. Невозможно в одну функцию или процедуру передавать массивы разной длины, так как они имеют разные типы.А где нет? А C++, например, `array<T, 10>` и `array<T, 11>` тоже разные типы. В паскале есть и динамические массивы - `array of real`. Днищенский он совсем не поэтому.
Убогие какие-то функции получаются. И всё из-за одного формального параметра размера массива?
поэтому удобно передать информацию: указатель на массив определенных элементов и количество элементов. Для меня это естественно.
Не забывайте Си разрабатывался как язык для написания операционной системы.
Да даже на си так можно. Если нужно.typedef struct array10_t { arr[10] };
vs
typedef struct array11_t { uint8_t arr[11] };
И далее вы это by value или by pointer уже не сможете перепутать. Что так то хорошо - спасет от случая когда вы 11-й элемент в массиве на 10 дереференсить пытались. Не то чтоб это совсем не получится, но это будет минимум баг, максимум вулн.
Упс, название типа потеряно. Примерно так: typedef struct array10_t { arr[10] } array10_t;
Там точно не ":=" ? А днищенство языка там начинается с 1. Потому что.
Все нормальные люди считают с 1, в нормальных языках типа Фортрана, Паскаля тоже с 1, в Ада - используются range, в математике нумерация с 1.
И только отбитые сишники решили, что делать индексом сдвиг указателя на голову массива это офигенная идея. К сожалению этого овнокод победил, и остальные начали делать также.
> Все нормальные люди считают с 1, в нормальных языках типа Фортрана, Паскаля
> тоже с 1, в Ада - используются range, в математике нумерация
> с 1.Ни один истинный шотландец...
А вы по утрам не приходите в канцтовары покричать на линейки и рулетки? )
Вот, такие же "нормальные" люди, наверно, изобретают лифты с кнопками "4 3 2 1 -1 -2" )
Докажите, что для написания ОС такая нумерация было бы лучше?
> в математике нумерация с 1.Нет, в математике нумерация оттуда, откуда удобно. Твоё математическое образование видимо упустило такую тему матана как ряды, где используется исключительно нумерация с нуля, потому что индекс 0 очень удобно порождает показатель степени 0, который даёт нам член ряда без x (c x в нулевой степени). Без него пришлось бы писать конструкции типа x^{i-1}, что увеличивает количество писанины.
Так переписывай на Модулу скорее. Модула-2 это же продвинутый Паскаль. Считай это для тебя будет рывок вперед. Это как с Перла перейти сразу на Раку.
Вряд ли будут переписывать. Вот, если б был delphi диалект object pascal, то можно было бы и готовые наработки использовать, а если в одном проекте на gcc без бубнов можно было бы совмещать код на разных языках, так что то уместне было б и на objeсt pascal писать.
А Модула.. это после деревянных древних Паскалей шаг вперёд, а после Делфи скачок назад.
Ну так бы и сказал сразу, что мол без ООП Дельфи как программист ты никто.
> Это как с Перла перейти сразу на Раку.Т.е. очередное нафиг нужное хзчто? На этому раке никто как раз и не прогает, во всяком случае, перловка попадается а раки нет :)
> эти старенькие плохонькие языкиЭто просто феерия какая-то - любитель одного старенького плохонького языка опускает другие старенькие плохонькие языки. Во-первых, не стыдно? Во-вторых, какое после этого право ты имеешь называть уродами тех кто критикует твой выбор паскаля?
> Хотя Паскаль мощнее и лучше и проще и изящнее Модулы и Фортрана
Во-первых, нет. Во-вторых, даже если бы и был, это чести не делало бы ни ему, ни тому кто на нём пишет. Лучший среди худших, то ещё достижение.
> И не видно что кто-то ненавидит ... А вот Паскаль ненавидят, и там и тут лезут уроды с критикой
Давай я объясню почему. Во-первых, на модуле и фортране была написана (и всё ещё написаны кое-где) куча высокоответсвтенного и научного софта. А паскаль никогда не был ничем серьёзнее языка для обучения детей. Во-вторых, на модуле и фортране ничего нового не пишут, потому что уровень тех кто на них может писать позволяет осознать их неприменимость в современном мире. А на паскале пишут, как раз потому что это школьный уровень которого даже на осознание того что для серьёзных задач он не подходит не хватает. Пик глупости из эффекта Даннинга-Крюгера, наипоказательнейший пример. И пишут они, надо сказать, соответственно, и вообще этот уровень торчит отовсюду вплоть до организации репозитория, коммитлогов (да-да, вот эти коммиты с мессаджами "fix" и "continue") и стиля общения.
И это только половина проблемы. Ладно дети, ладно не умеют программировать - какая разница если на выходе что-то есть и этим можно пользоваться. Но чтобы этим пользоваться надо притащить целую экосистему маргинального языка со своими правилами, своими кривыми модулями, своей кривой сборкой, своими багами и кучей проблем с переносимостью и совместимостью, причём всё это не исправляется потому что паскаль уже никому не нужен, и дальше будет только хуже. Поэтому даже мантейнеров (которые, вообще, по природе своей любят ковыряться в сложных вещах) заниматься этим не находится. Поэтому cudatext и опакечен в полутора дистрибутивах за свои, сколько там, 6-7-8 лет истории, а использовать блобы, по крайней мере под linux, дураков нет, и собирать самим тоже нет, потому что это не `cmake && make && make install` или, упаси господи, `cargo build` как в современных экосистемах, а адовый квест. А вот среди виндузятников наверное у вас основная аудитория и есть, как и у total commander. Эти всё в рот тащат, к тому что всё ломается на ровном месте привыкли, благодарная аудитория.
>Лучший среди худших, то ещё достижение.А вот несогласен с такой оценкой Паскаля.
Вполне успешный язык, с хорошей системой типов, и использовался для вполне нужного софта.
Да и простота его (см. обвинение в "школьности") привела к тому, что какой нибудь КМС^w КТН для проверки рабочих гипотез ваял на паскале как мог. А мог обычно почти никак (ой видел я этот поток учёного сознания), он же не профессиональный программистъ (Сейчас так же херово ваяют на питоне, хороший язык, да? да на матлабе ещё. пофиг, главное, гипотезу посчитать)
Другое дело, что вышедший через два года C предложил несколько интересных вещей (например, функции с переменным количеством аргументов) явно с учётом особенностей других языков (а кто там был массовый? Фортран, Алоголы ); и синтаксически чётко разделял язык и библиотеку, чем лучше подходил как для системного программирования, так и для кросс-платформенного. И вот "профессионалы" уже хают дедушку, который им всё это богатство на блюдечке принёс, научил, грабельки показал где лежат... ладно, Остапа понесло...
Да и время было такое, по сути, они все были первопроходцы в этом сложном деле.
> А вот несогласен с такой оценкой Паскаля.Вы не написали с чем именно вы не согласны. Написанное вами написанному мной нигде не противоречит.
> Вполне успешный язык
Согласен. Так, весь ныне забытый старый хлам был когда-то успешным.
> с хорошей системой типов, и использовался для вполне нужного софта.
Чем именно хороша его система типов? Не к её плохости, а к тому что она ничем не выделяется из массы всех паскале- и си-подобных языков.
> Да и простота его (см. обвинение в "школьности") привела к тому, что какой нибудь КМС^w КТН для проверки рабочих гипотез ваял на паскале как мог. А мог обычно почти никак (ой видел я этот поток учёного сознания), он же не профессиональный программистъ (Сейчас так же херово ваяют на питоне, хороший язык, да? да на матлабе ещё. пофиг, главное, гипотезу посчитать)
В школьности было не обвинение, а констатация факта, и описанный кейс с КТН никакого негатива не вызывает. Однако одно дело что кто-то что-то там делает для себя на коленке как умеет и как его полностью устраивает - это его личное дело. А другое - когда делается продукт для внешнего потребителя, которому неизбежно приходится брать на себя риски. А их и сам паскаль, и его экосистема, и квалификация автора который считает что на нём можно писать прикладуху, несут немерянно.
Большое спасибо. Что просветили насчет Модулы и Фортрана, буду знать что на них сделано много научных библиотек.
А не надо ёрничать. Действительно, просвещайтесь:https://en.wikipedia.org/wiki/List_of_numerical_libraries#Fo...
За что их ненавидеть? Про модула не знаю ничего, а на фортране сегодня все наиболее производительные вычисления, в том числе на больших компах. Это стандарт. И зря что ли все проприетарщики пилят всё новые и новые компиляторы фортрана? И ни одного для других языков. Это, к слову, возможно, не в последнюю очередь, из-за того, что в том же гцц весьма убогий компилятор фортрана, и нормальную поддержку железа добавить проще в поделки поверх llvm. А из доступного любому обывателю прямо сегодня и сейчас есть mkl -- это наиболее производительная либа из альтернатив лапаку (а их полно) с SIMD и всем остальным. Только вот практически фортран не годится ни для чего кроме перемножения матриц. Исторически так сложилось, что его компиляторы генерировали код лучше сишных, но вот написать на фортане приложуху? Тут лучше взять что-нибудь более человеческое. А фортрану оставить математические вычисления. К слову, такой язык как ада тоже никто не ненавидит. У него есть свои применения, в отличие от того же раста. Что до паскаля, то это просто мусор, для тех, кто не осилил никаких других языков, никакого хейта тут нет. Разве что сломал мозги некоторым, все у них уроды. Ты же не будешь хейтить кувасик или тех, кто на нём сегодня кодит? Вот и паскаль там же.
может оказаться что дело совсем не в производительности, а в огромных горах старых наработок, которые с нуля не так чтобы сильно хотят переписывать. Ведь зачастую проще что-то что уже есть допилить, чем что-то полностью с нуля создавать
Этот аргумент работает с коболом. Но где ты его помимо банкоматов увидишь сегодня? Фортран выбирают именно из-за того, что он хорош для вычислений.
Вот за это ТоталКомандер, АИМП и прочие школоподелки из 90ых презренны.
А, ну да, Паскаль не старенький ;)
Классический Паскаль старше C. Это на заметку так.
Но да, современные диалекты современны в меру умений разработчика. В гибкости отстают от языков с непрямой работой с памятью, а в производительности от языков а-ля ассемблер (как классический C). Весь антихайп из-за того, что этот язык программирования требует слишком серьёзной подготовки для написания адекватного кода.
Паскаль старенький. Но он вбирает в себя новые веяния. Дженерики, анонимные функции, for-in, КОРБА-интерфейсы, атрибуты в [], поддержка разных CPU + OS, и т.д. Все это появляется.
Ну и как там в паскале с параллелизмом в гетерогенных вычислительных системах ??
Пакет под Альт Линукс есть или самому собирать, я про CudaText?
Как там дела у Iain Buclaw?
Всё отлично :)
D живее всех живых
Не ну модула-2 топчик, кто бы спорил.
> В соответствии с новой схемой нумерации выпусков, версия 13.0 использовалась в процессе разработкиКак же достало, что каждый проект придумывает свою невиданную ранее систему версионирования. Были же семантические версии десятками лет, Но нет: надо, чтобы люди при каждом релизе вспоминали, что том разработчики имели в виду - для каждого доброй дюжины проектов.
> Как же достало, что каждый проект придумывает свою невиданную ранее систему версионирования. Были же семантические версии десятками лет, Но нет: надо, чтобы люди при каждом релизе вспоминали, что том разработчики имели в виду - для каждого доброй дюжины проектов.Нормальным людям (включая мантейнеров пакетов и разработчиков) это нахрен не нужно, вообще всё равно какая там циферка где меняется. И это правильно, потому что ничего через циферки не выразить, и semver доказал свою полною несостоятельность.
> И это правильно, потому что ничего через циферки не выразитьМожно выразить масштаб изменений.
> semver доказал свою полною несостоятельность
Разве что как раз этим уникумам, которые изобретают свой велосипед.
> Можно выразить масштаб изменений.Нет, можно выразить только наличие очередного релиза и упорядочить релизы (и то только в рамках одной релизной ветки), масштаб изменений выразить нельзя от слова вообще, потому что он для каждого потрелибеля значит разное и для большинства применений неизмерим вовсе. А если бы даже масштаб и можно было как-то выразить, то использовать его всё равно никаким осмысленным образом не получилось бы.
Напомню что semver, одна из немногих схем _осмысленного_ версионирования, отталкивается не от непонятного масштаба, а от конкретного (на первый взгляд) свойства - изменений в API (patch = нет изменений, minor = есть совместимые, major = есть несовместимые). Однако эта схема не работает потому что, с одной стороны, на практике оказывается что любое наблюдаемое изменение является несовместимым (поэтому исправление бага в minor ломает тех кто на этот баг заложился), с другой - не все несовместимые изменения API аффектят всех (поэтому major изменение может вообще ничего не затронуть в потребителе). При этом а) API имеет смысл только для библиотек, при том что не все проекты библиотеки б) почти половина проектов не заявляют стабильного API (версия 0.*).
Поэтому нет, версии ничего ни количественно, не качественно не выражают, никогда не выражали и не будут, а требовать этого могут только не разбирающиеся в разработке дурачки.
> Поэтому нет, версии ничего ни количественно, не качественно не выражают, никогда не выражали и не будут, а требовать этого могут только не разбирающиеся в разработке дурачки.Ох уж эти опеннетные умники, разбирающиеся в разработке. Ты сам себе противоречишь, утверждая, что семантика есть, но при этом она ничего не выражает. Семантика есть и у нового способа версионирования GCC, но она нестандартная, и в этом как бы вся претензия.
> свойства - изменений в API
Не только изменений в API, но и любого функционала софта в целом (не обязательно библиотек). А еще у библиотек есть ABI. При этом ты же сам написал, что patch - это багофиксы, minor - новый совместимый функционал, а major - огромные несовместимые изменения. Это как бы и есть масштаб и тип изменений, не?
> любое наблюдаемое изменение является несовместимым (поэтому исправление бага в minor ломает тех кто на этот баг заложился)
Во-первых, баги фиксят в path. Во-вторых, если у кого-то хватило ума заложился на баги - это их личные проблемы. Какое отношение это имеет к системе версий и ее семантике?
> не все несовместимые изменения API аффектят всех
Опят же, какое отношение это имеет к системе версий? Какое мне дело, аффектит ли оно "всех", если я работаю над конкретным проектом или с конкретным софтом?
> поэтому major изменение может вообще ничего не затронуть в потребителе
Нет, не может, ибо это уже не изменения уровня major, а как раз какая-то новая нескучная семантика.
> почти половина проектов не заявляют стабильного API (версия 0.*).
Ну вот ты сам упомянул о еще одной семантике - пре-релизе. И тут же утверждаешь, что версия не говорит ни о чем.
> Ты сам себе противоречишь, утверждая, что семантика есть, но при этом она ничего не выражаетЯ такого не утверждал, научись читать - я привёл semver как пример _попытки_ сделать вид что семантика есть, и показал почему это не работает.
> Не только изменений в API, но и любого функционала софта в целом (не обязательно библиотек)
Нет, только изменений в API, потому что API это контракт, а только при наличии контракта можно говорить нарушается он или нет. Про изменение "любого функционала" ничего нельзя сказать. Может ты опечатку поправил в выводе программы, и для тебя это patch, а для того кто этот вывод решил парсить и у него сломалась регулярка это breaking change. Собственно, то же возможно и при обработке того что вернула библиотека, поэтому semver и не работает.
>> не все несовместимые изменения API аффектят всех
> Опят же, какое отношение это имеет к системе версий? Какое мне дело, аффектит ли оно "всех", если я работаю над конкретным проектом или с конкретным софтом?Автор, по semver, должен бампать major при любом несовместимом изменении в API. При этом клиент может эту часть API вообще не использовать. В итоге даже забыть что semver не работает, и завязаться на его гипотетическую семантику, которая позволила бы нам, например, описать диапазон версий зависимости нашего проекта как `>=17 <18`, надеясь получать обновления в рамках 17 мажорной версии и при этом не сломаться, мы получим хрена лысого.
То, что вы хотите от semver чего-то, что он не может — не проблема semver, это ваша проблема.
>И это правильно, потому что ничего через циферки не выразить, и semver доказал свою полною несостоятельность.Ты когда-нибудь зависимости руками собирал?
> Были же семантические версии десятками лет$ less --version
less 629 (PCRE2 regular expressions)
Copyright (C) 1984-2023 Mark Nudelman
И чем тебя не устраивает:GCC 13.1 released [2023-04-26]
GCC 12.2 released [2022-08-19]
GCC 10.4 released [2022-06-28]
GCC 9.5 released [2022-05-27]
GCC 12.1 released [2022-05-06]
GCC 11.3 released [2022-04-21]
GCC 11.2 released [2021-07-28]
GCC 9.4 released [2021-06-01]
GCC 8.5 released [2021-05-14]
GCC 11.1 released [2021-04-27]
GCC 10.3 released [2021-04-08]
GCC 10.2 released [2020-07-23]
GCC 10.1 released [2020-05-07]
GCC 9.3 released [2020-03-12]
GCC 8.4 released [2020-03-04]
GCC 7.5 released [2019-11-14]
GCC 9.2 released [2019-08-12]
GCC 9.1 released [2019-05-03]
Тем, что половины номеров тут нет. Например, 10.0.0 или 12.1.1. То есть вы предлагаете мне просто запомнить, какие версии есть, а каких нет.
10.0.0 или 12.1.1 - это не релизные версии, это текущие версии, над которыми ведётся работа, по завершении которой эти версии получают другие номера - в данном случае 10.1 и 12.2.
Мне интересно, почему в языковые расширения (https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html , https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html) до сих пор не добавили свойства (properties), реализованные во многих языках, в том числе и во многих расширениях С++ (как минимум в MSVC и C++Builder). Реально полезная штука как минимум для изучения огромных унаследованных кодовых баз, когда нужно перехватить обращение к тому или иному объекту/полю. Причем полная эмуляция этой фичи перегрузками операторов невозможна. Куда можно написать предложение разработчикам компилятора?
Потому что свойства это только для тех, кто очень полюбил визуальное "программирование" мышкой. А для тех кто текстом программирует, свойства это как собаке пятая лапа. get-теры set-теры тебе в помощь.
Вы считаете, что без GUI дизайнера интерфейса писать гораздо быстрее, чисто в тексте, не видя в процессе того что получается? ;)
То то чистый C++ для GUI не очень удобен.А get-теры и set-теры, это почти как begin и end и пятая нога. С одной стороны, работает - не трогай, но и если не развиваться, "засахарится" и морально устареет.
> Отправлено _kp, 27-Апр-23 01:38Вы считаете, что без GUI дизайнера интерфейса писать гораздо быстрее, чисто в тексте, не видя в процессе того что получается? ;)
Можно и без дизайнера видеть что получается, в тч в реалтайме. Так например используют vim для написания статей latex в pdf. Или тестировщики так тестируют gui.
Дизайнеры это по сути комбайн, но все то же самое может и отдельно работать.
Ну а в идеале не должно быть необходимости постоянно смотреть что получается. Результат итак должен быть очевиден (так например было с html в конце 90ых).
Программист совсем ничего не должен знать про GUI. GUI должен делать дизайнер. Возможно в Фигме, а программист должен брать оттуда циферки и вставлять в своё приложение. Возможно это даже промежуточный программист, которого можно назвать верстальщиком. Никаких других способов получить красивый дизайн не существует.
Программисту надо иметь права на отламыванию пальцев дизайнеру, если что.
Даже с таким правом и даже с визуальным программированием у программиста дизайн будет полный ... отстой. Обычно даже UX отстой чего уж там.
У многих проектов 2 - 3 разработчика, а то и всего один. Вот теперь если они ещё и десигнеров для проектов искать начнут, то на собственно разработку времени не останется. Полезного кода больше не увидим.
Значит дизайн будет фи ка лия. С этим ничего нельзя поделать это данность. Это надо принять.
Свойства как концепция вообще никакого отношения к визуальному программированию не имеют. Это особая трансформация синтаксического дерева, позволяющая прозрачно заменить обращения на чтение и на запись к некоторому полю данных на вызовы функций. Здесь существенна именно прозрачная замена - то есть при замене свойства на поле и обратно остальной код менять не требуется.
> Свойства как концепция вообще никакого отношения к визуальному программированию не имеют.Ну в чистом виде не имеют, но значительно упрощают графический дизайнер интерфейса, и не только его.
В общем, было бы полезно добавить.
> А для тех кто текстом программирует, свойства это как собаке пятая лапа. get-теры set-теры тебе в помощь.Отличная логика. Добавили operator[], перегрузку, пользователськие операторы, RTTI, но свойства - "собаке пятая лапа".
Пишите на Vala, там есть свойства и в довесок GObject.
лол, заставил меня вспомнить те годы. Да не, проперти - это костыль какой-то. Если что и было нужного в быдлере - это _кложуре для коллбэков.
Это целиком и полностью покрывается возможностями std::function
В спортлото напиши, Си сделан не для скрытой сложности, в противном случае там давно была бы перегрузка операторов уже давно.
Сборка toolchain с GCC всё так же является чёрной магией с кучей заклинаний?
бекенды для го и хруста....
этим вообще кто то пользуется лол
Те кто не хотят борова чекать.
В сборочных дистрах (Gentoo, LFS) не пользуются ржавым из-за необходимости тащить его компилятор. После добавления ржавого в gcc популярность программ на нем теоретически должна вырасти. У меня в системе, например тяжелая математика на foltran и наличие этого компилятора не особо мешает.Go не пошел у меня из-за его "менеджера пакетов" после попытки установить ipfs выкинул. Ржавый тоже может не пойти по этой причине.
Не со всем согласен: https://blogs.gentoo.org/mgorny/2021/02/19/the-modern-packag.../ слишком большая "дроблённость" rust & go способствует внедрению закладок в используемые либы. Однако обязательное внедрение подписей PGP может помочь решить проблему.
Некогда, когда ещё программировал и занимался наукой, переписал критическую часть рассчётной программы (МКЭ) на Си, и скорость выросла в разы. Фортран - это хорошо, но очень уж не оптимизированно.
Современный Fortran - вполне себе годный инструмент. Для realtime, может, и не подойдет, но для расчета эмуляций процессов при ядерном взрыве с распаралеливанием вычислений - вполне себе. Многое зависит также и от квалификации программиста.
Ну так напиши майнер на фортране, посмотрим сделает ли он по мегахешам сишный.
К сожалению, для firefox уже нужно ставить Rust. Но с ним есть одна дикая вещь в gentoo:https://bugs.gentoo.org/735154#c3
# Enable all LLVM targets unconditionally. Unfortunately, disabling
# targets tend to break reverse dependencies (e.g. Rust) and we are yet
# to find a clean way of resolving that. Compared to the damage
# potential, the increase of build time is a minor problem. Users who
# really insist of building a smaller system can un-force the flags
# at their own responsibility.
>[оверквотинг удален]
>=sys-devel/clang-14 llvm_targets_VE
>=sys-devel/llvm-13.0.1_rc llvm_targets_AArch64 llvm_targets_AMDGPU
>=sys-devel/llvm-13.0.1_rc llvm_targets_ARM llvm_targets_AVR llvm_targets_BPF
>=sys-devel/llvm-13.0.1_rc llvm_targets_Hexagon llvm_targets_Lanai
>=sys-devel/llvm-13.0.1_rc llvm_targets_MSP430 llvm_targets_Mips
>=sys-devel/llvm-13.0.1_rc llvm_targets_NVPTX llvm_targets_PowerPC
>=sys-devel/llvm-13.0.1_rc llvm_targets_RISCV llvm_targets_Sparc
>=sys-devel/llvm-13.0.1_rc llvm_targets_SystemZ llvm_targets_WebAssembly
>=sys-devel/llvm-13.0.1_rc llvm_targets_X86 llvm_targets_XCore
>=sys-devel/llvm-14 llvm_targets_VEи это при том, что rust тащит свою собственную llvm.
Как так то?!!
Пьющие кровавые смузи хипстеры.
Свободные и независимые хипстеры, которые за чистоту кода против корповых компиляторов.
>Объявлена устаревшей поддержка Solaris 11.3Хотя бы 11.4 поддерживается.
Решил тут попробовать G++. И что?
1) Возможности явно указать точку входа прямо в коде нет, хотя она была в любом древнем компиляторе. Отрубаешь stdlib и приходится указывать точку входа через командную строку.
2) Отрубить .edata если она пустая возможности нет, даже при использовании gc-sections
3) Отрубить hintы в импорте возможности нет
4) 64х битный и 32х битный компиляторы ведут себя по разному, так что везде приходится тыкать условную компиляцию.
Разве манипуляции с секциями ELF не задача линкера?
Просто тут другой под к вопросу. Один ламеровендузятский, где всё пихают в кучу, и другой нормальный, где инструменты занимаются своими вещами и дают контроль программисту. Я так понимаю, в этом суть проблемы.
В Виндосе в MSVC точка входа задавалась ключём линкеру /ENTRY:function. В ассемблерах можно в исходном тексте указывать. Может он так троллит?
> 1) Возможности явно указать точку входа прямо в коде нет,Си это не ассемблер. Но если сильно хочется, линкерскрипт или командлайн к вашим услугам.
> хотя она была в любом древнем компиляторе.
Не есть стандартный си и никак не регламентировано. По факту в gcc можно что угодно сделать, как микроконтроллерщик говорю.
> Отрубаешь stdlib и приходится указывать точку входа через командную строку.
Можно в линкерскрипте указать. Да и хотели вы наверное что-то типа:
-fno-common -fno-builtin -nostdlib -ffreestanding или около того...А может еще и это, если про gc sections в курсе:
-fdata-sections -ffunction-sectionsЛучше всего оно в паре с LTO, если тот выносит лишнее (умеет!) есть __attribute__(used).
> 2) Отрубить .edata если она пустая возможности нет, даже при использовании gc-sections
Можете отрубить все что угодно - добро пожаловать в чуднй мир линкер скриптов. Как хотите так и компонуйте свой бинарь. Все гибко и настраиваемо. Есть даже директива DISCARD для неугодных вам секций. Если они были нужны и не стало работать кто ж вам виноват? :)
> 3) Отрубить hintы в импорте возможности нет
А что такое "импорт" в вон том flat binary фирмвари например? :)
> 4) 64х битный и 32х битный компиляторы ведут себя по разному, так
> что везде приходится тыкать условную компиляцию.А они и не обязаны себя одинаково вести. Они обязаны имплементить стандарт сей (ну или плюсов).
GCC 13 и не слова про #include <cstdio>.
>cstdioА это ещё что?
stdio.h
>>cstdio
> А это ещё что?https://runebook.dev/ru/docs/cpp/header/cstdio
Почти в каждом 1-ом патче для C++ пакетов в имени которого присутствует gcc13.
Можно оффтоп ради саморазвития, раз уж тут околосистемные погромисты собрались. В линукс/бсд/солярисах такой же идиотизм с исполняемыми файлами как и в шиндовом EXE, когда в заголовке прописываются смещения в коде, которые нужно обновлять для выделенного блока памяти каждый раз при запуске?
В виндовых x64 exe этого уже нет, так как код стал PIC-подобным
А если какой-нибудь кульхацкер на ASM'е наваяет с прямой адресацией?
Кульхацкер если что наваяет, то потом обязательно проверит. Тем он и отличается от анонимного эксперта.
Точнее, не в заголовке, а в таблице релокаций. Релоки не обязательны для запуска, раньше по умолчанию в exe их не было. Нужны они для загрузки по любым адресам. Можно писать код так, что релоки не понадобятся. Компиляторы-линкеры генерировали релоки, поскольку код получался более компактным. Зависит это от процессора, а не от ОС. В gcc ищите в справке position-independent code.И кстати "шиндовый EXE" грамотно называется PE/COFF. А "COFF was introduced in 1983, in AT&T's UNIX System V". ;)
>И кстати "шиндовый EXE" грамотно называется PE/COFF. А "COFF was introduced in 1983, in AT&T's UNIX System V". ;)Открою тебе срашную тайну! Тс-сc! Тока никому не говори: "DOS/Windows - это изуродованный Xenix". Ублюдок Билли специально путь в файловой системе обозначил обратным слешем (\), чтобы все его продукт приняли за оригинальную, с чистого листа написанную ОС!
Это для меня не тайна, что тороидального Анонима (-) лучше не читать. 86-DOS Билли купил у Тима Патерсона, а NT у DEC вместе с командой разработчиков VMS.
Только UNIX System V COFF был без всяких там PE - M$ улучшайзингов.
> Только UNIX System V COFF был без всяких там PE - M$
> улучшайзингов.Разверните мысль, приведите парочку для примера.
> такой же идиотизм с исполняемыми файлами как и в шиндовом EXE,
> когда в заголовке прописываются смещения в коде, которые нужно обновлять для
> выделенного блока памяти каждый раз при запуске?В 32 bit x86 - а куда вы денетесь? У x86 код не является position independent и его нельзя перенести в другие адреса без сильного патчинга программы, потому что проц режимами адресации не вышел - не умеет относительно PC (IP) референситься, например. Это вообще от ОС не зависит, только от архитектуры проца. Можно еще грузить все в фиксированые адреса но это не гибко и может быть неудачно для секурити. Если хакер знает все адреса функций, ему так сильно удобнее атаку развивать.
В x86-64 все заметно приличнее, но там тоже смотреть нюансы надо.
Серверы, сервисы и прочая мутата в компиляторах...докатились.
>В состав GCC принят фронтэнд для сборки программ на языке программирования Modula-2.Его используют только в российской оборонке! ИМХО, в наборе компиляторов GCC он не нужен.
>После доведения фронтэнда до готовности (ожидается в следующем выпуске), штатный инструментарий GCC сможет использоваться для компиляции программ на языке Rust без необходимости установки компилятора rustc, построенного с использованием наработок LLVM.Проблема не в том, что есть он в наборе компилятор или нет. Должно произойти 2 вещи.
1. Язык Rust должен одобрить Столлман.
2. Язык Rust должен иметь копилефтную лицензию (в том числе и все библиотеки в Cargo).
1. Всем по... на деда
2. Раковый копилефт оставьте себе. Тут свободная лицензия.
Свободной считается только лицензия типа копилефта. Это отражено на сайте GNU и FSF и много раз отмечено в научных трудах и СМИ. Лицензии типа Mozilla_PL, БЗД (всех 4-х клаусов), МИТ-щина, Апаче, "Общественное достояние" считаются пермиссивщиной, их ещё называют "Открытый код (Open Source)".
Свободной по чьему мнение? По мнению гнутеллы и фсф?
Ахаха, ну разумеется это рачье будет кричать что только их лицухи по настоящему свободные.BSD, MPL, MIT, PublicDomain - вот где настоящая свобода, а не швaбoдka® гплнутых фанатиков.
Люто плюсую твои слова, брат Аноним.
Главное, чтобы swap не рос
Rust же защищает от Use after free ;)
> Rust же защищает от Use after free ;)Вон тот список CVE готов поспорить с этим храбрым утверждением.