LINUX.ORG.RU

Новое слово в программировании на C: штатное определение количества элементов в массиве

 ,


1

2

Привет, ЛОР!

Тихо и незаметно во всеми нами горячо любимый язык программирования Си решили наконец добавить новый оператор, возвращающий количество элементов в массиве. То есть, аналог вот такого:

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

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

Ссылка на опрос: https://www.allcounted.com/s?did=qld5u66hixbtj&lang=en_US

Статья от автора предложения: https://thephd.dev/the-big-array-size-survey-for-c

Что скажут эксперты в программировании на C по поводу этого нововведения? Нужно ли оно? Станет ли язык Си ещё лучше?

★★★★★

Последнее исправление: hobbit (всего исправлений: 2)
Ответ на: комментарий от vbr

Пользуешься ведь?

Нет, еще какие-то там алгоритмы будут за меня решать как мне код форматировать.

Во первых, точку с запятой так случайно не поставлю. И визуально это выделяется. Во вторых, компиляторы предупреждают о такой конструкции.

jpegqs
()
Ответ на: комментарий от hateyoufeel

Руки у тебя не из того места, чинильщик. :) Как, впрочем, у всех растафилов.

Ни разу не видел чтобы что-то писали на сишке ради написания на сишке. Так же как ни разу не видел чтобы что-то написали на расте не ради написания на расте.

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Я поймал себя на том, что мне нравится писать код на 32-бит ARM ассемблере. Даже если и так всё достаточно быстро работает.

Просто задачка интересная, даже не верится порой как можно код сокращать. Воспринимается как игра. Ну, если не всё подряд переписывать, а интересные тебе алгоритмы.

jpegqs
()
Ответ на: комментарий от anonymous

Это твой недостаток.

Нет, просто я не говнокодер как ты.

Ну кто же виноват, что ты ни разу не писал серьезных программ и не понимаешь почему рефакторинг — один из основных факторов сишных багов?

Во-первых, если у тебя рефакторинг вот настолько ломает код, то значит ты - рукожоп. Во-вторых, источник сишных багов - это невнимательность, поэтому я и предложил вместо синтаксического сахара, который не нужен при прямых руках добавить нормальные фичи в стандарт сишки, которые в GCC были «испокон веков».

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

https://pastebin.com/wHxTrbPz

Сходу с места. stdatomic.h и всё сопутствующее это не ANSI C и не C99, а C11. Не слишком ли ново для человека мастурбирующего на ANSI C?

#include <stdbool.h>
#include <stdint.h> и сопустствующее

C99

#endif // NRF52833_XXAA
// NOLINTNEXTLINE(misc-misplaced-const)
// NOLINTNEXTLINE(bugprone-implicit-widening-of-multiplication-result)

Однострочные комментарии из C99.

nrfx_usbd_transfer_t transfer = {.p_data = {.tx = data}, .size = 2};

Designated initializers из C99. Алсо переменная объявленная не в начале блока. Тоже C99.

Немного практикую

Оно и видно, что практикуешь консерватизм, но явно совсем немного. Самую чуточку и только в спорах в интернете.

В остальном кстати вполне аккуратненько. Мне нравится :)

a1ba ★★
()
Последнее исправление: a1ba (всего исправлений: 1)
Ответ на: комментарий от jpegqs

Вы еще не видели как я использую оператор запятая, дурной пример подхватил из кода OpenCV.

Don’t put multiple statements on a single line unless you have something to hide (c) Linux kernel coding style

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

Конечно лучше писать код так, чтобы ни то, ни другое не пригождалось, но в процессе поддержки чужого кода есть смысл обратить на них внимание.

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

А VLA в отличие от alloca стандартен.

Да, но можно ли сделать VLA в цикле? Если выделить VLA в блоке, то непонятно время жизни. Указатели от alloca гарантированно живут до выхода из функции. И бы предпочел использовать alloca.

jpegqs
()
Ответ на: комментарий от Stanson

Как, впрочем, у всех растафилов.

Так я не растофил. Я на нём сам не пишу лол.

Ни разу не видел чтобы что-то писали на сишке ради написания на сишке. Так же как ни разу не видел чтобы что-то написали на расте не ради написания на расте.

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

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

Я поймал себя на том, что мне нравится писать код на 32-бит ARM ассемблере. Даже если и так всё достаточно быстро работает.

То, что тебе лично нравится, не играет никакой роли. Ты можешь хоть на Brainfuck программировать. Проблемы начинаются, когда в твоём коде должен копаться кто-то другой.

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

В прошлый раз, когда мы смотрели твой сишечный код, там был стек просран подчистую

Нет, там у read сразу после успешного open не проверялся код возврата на предмет ошибки. :) Что, впрочем, совершенно бессмысленно, ибо если после успешного open приезжает ошибка read, то судьба приложения - это меньшее что должно беспокоить.

именно поэтому именно тебе стоит писать на расте.

Раст вообще никак не мешает просрать стек. Вот совсем. Оно даже рекурсию бесконечную жрёт без единого писка.

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

Нет, там у read сразу после успешного open не проверялся код возврата на предмет ошибки. :) Что, впрочем, совершенно бессмысленно, ибо если после успешного open приезжает ошибка read, то судьба приложения - это меньшее что должно беспокоить.

Читаешь из сетевой файловой системы, получаешь ошибку -> ASSISTED CODE EXECUTION. Обожаю сишку.

anonymous
()
Ответ на: комментарий от Stanson

Лучше бы сделали возожность использовать строковые константы в switch(x){ case "sometext": ... break; ... }. Или добавили бы векторы и матрицы в базовые типы данных и соответствующую арифметику

В C3 есть. :)

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

Раст вообще никак не мешает просрать стек.

А можно пруфы? Без unsafe{} только. Покажи нам, как ты переполнишь буфер на стеке в Rust.

Оно даже рекурсию бесконечную жрёт без единого писка.

Бесконечная рекурсия не ведёт к переполнению буфера на стеке и подмене адреса возврата из функции.

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

Похоже один понял что «просрать стек» означает переполнение стека, а другой имел в виду переполнение буфера на стеке. Надо использовать более точные определения.

jpegqs
()
Ответ на: комментарий от Skullnet

Нет, просто я не говнокодер как ты.

А я здесь причем? Я говорю про серьезные проекты, вроде Linux Kernel.

Во-первых, если у тебя рефакторинг вот настолько ломает код, то значит ты - рукожоп.

Все рукожопы. Не существует программистов нерукожопов. Поэтому компиляторные проверки, статические анализаторы, тесты, фаззеры, и так далее.

Во-вторых, источник сишных багов - это невнимательность

Это основное свойство человека – переключение внимания. Люди чисто физически неспособны долго фокусироваться, поэтому сишка тупо не расчитана на то, что на ней люди писать будут. Это язык для биороботов, которых нам не завезли. Ну или катов, но у катов лапке.

anonymous
()
Ответ на: комментарий от dataman

Это хорошее решение, чтобы никакой код не сломало своим появлением. Это имя каждый может переименовать макросом по своему вкусу. Хотя и без этого можно было реализовать макросом, очередное никчёмное нововведение.

jpegqs
()
Ответ на: комментарий от anonymous

Читаешь из сетевой файловой системы, получаешь ошибку -> ASSISTED CODE EXECUTION. Обожаю сишку.

Ну да, держать /tmp на сетевой файловой системе это несомненно распространённое решение которое стоит серьёзно учитывать при написании программ.

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

Ну да, держать /tmp на сетевой файловой системе это несомненно распространённое решение которое стоит серьёзно учитывать при написании программ.

Да-да, я знаю. Все сишные рукожопы так свои баги и объясняют. Чего стоит один только djb (на секундочку, автор половины современной криптографии), которому говорили «чувак, вот тут будет порча памяти», а он говорил «да не вы чо, ваще такого быть не может». В итоге оказалось, что может.

anonymous
()
Ответ на: комментарий от a1ba

ANSI C я бы при всём желании не смог использовать, т.к. там nrf5 sdk, который компилируется с c99.

И, повторюсь, от того, что я считаю эти фичи ненужными, они из языка не исчезают, и не использовать их из принципа это странно. Поэтому я их использую там, где уместно. Но всё равно считаю их ненужными. Не было бы atomic, использовал бы volatile, хоть семантика чуток другая, но по факту работало бы так же.

Я противник того, чтобы тащить в язык всё подряд. Но на развитие языка я не влияю, поэтому своё мнение - да, высказываю в интернете, но на практике естественно буду писать так, как в конкретной ситуации уместно. В описанной ситуации у меня конкретный sdk, переписывать который было бы верхом глупости, этот SDK настоятельно рекомендуется собирать конкретным gcc 9, и раз уж я в такую ситуацию попал с зафиксированной версией компилятора, то почему бы мне и не использовать все возможности.

Если надо будет писать программу без зависимостей - это другой разговор будет.

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

Эх, я бы проголосовал за len(x)

Тут надо понимать, что в языке уже есть sizeof anything, который менять не планируется. И добавлять рядом len(x) - ну совсем некрасиво. Всё же нужно somethingof x для симметрии.

А так - вроде в C++ есть std::size, который как раз для этого. В Общем полный разброд и шатание.

vbr ★★★★
()
Последнее исправление: vbr (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

А можно пруфы? Без unsafe{} только. Покажи нам, как ты переполнишь буфер на стеке в Rust.

В смысле «без unsafe{} только»? Тут вижу, тут не вижу? unsafe законная конструкция в языке.

В сишечке, например, тоже «буфер не переполнишь на стеке» если «без массивов/разъименований только»

Бесконечная рекурсия не ведёт к переполнению буфера на стеке и подмене адреса возврата из функции.

Вообще-то зависит от системы и организации стека. Или раст внезапно не портабелен?

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

Если надо будет писать программу без зависимостей - это другой разговор будет.

Ну напиши. Не используй, по-твоему, не нужного.

Но жаль, тут не получится оправдаться тем, что у тебя какой-то там сдк где за тебя уже всё решили.

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

В смысле «без unsafe{} только»? Тут вижу, тут не вижу? unsafe законная конструкция в языке.

Ага, за использование которой могут и по щщам надавать. Если для реализации той или иной фичи не нужен unsafe{}, значит его в коде быть не должно. Ты же не долбишься в inline asm в сишечке на каждый чих?

Вообще-то зависит от системы и организации стека.

Itanium сдох, у остальных двух архитектур на рынке адрес возврата на стеке. У RISCV отдельный регистр под это, но это только для текущей функции.

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

Ты же не долбишься в inline asm в сишечке на каждый чих?

Так я и массивы на каждый чих не использую.

Itanium сдох, у остальных двух архитектур на рынке адрес возврата на стеке. У RISCV отдельный регистр под это, но это только для текущей функции.

Стек лишь частично реализован в железе в виде pop/push/call/ret инструкций или подобных. Всё остальное, включая выделение памяти под него, делает либо ОС, либо загрузчик либо сама софтина. Там дофига может быть всяких сюрпризов. Например если стек вылезет с отмапленной в rwx RAM на отмапленную в rwx ROM, то внезапно рекурсия как нефиг делать может привести к куче весёлых последствий.

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

Так я и массивы на каждый чих не использую.

Мне нравится в сишке вот эта история: программисты настолько запуганы, что боятся использовать простейшие концепты языка, лишь бы не получить RCE. По-моему, только JS так же смог затравить своих адептов, больше никому не удавалось.

anonymous
()
Ответ на: комментарий от Stanson

Так я и массивы на каждый чих не использую.

Не осилил, да? Но мне нравится, что ты сравниваешь такую банальную вещь как массивы с потенциальным отстрелом жопы (т.е. unsafe{}).

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от anonymous

Мне нравится в сишке вот эта история: программисты настолько запуганы, что боятся использовать простейшие концепты языка, лишь бы не получить RCE.

Что за проекции глупые? Надо - используют, не надо - не используют. Используют даже alloca и о ужас, calculated goto. В сишке, к счастью, не реализовали всякие влажные мечты религиозных идиотов о запрете т.н. bad practice и пр. бред.

А растаманы программистами не являются, так что для них придумали unsafe чтобы они не использовали простейшие концепты программирования, типа адресной арифметики и пр. Кстати расту есть куда развиваться - ещё надо ещё битовые операции объявить например inapropriate{}. А то сложна и ошибки же.

По-моему, только JS так же смог затравить своих адептов, больше никому не удавалось.

У JS нет адептов, к сожалению. Есть только вебмакаки. А так - неплохой встраиваемый язычок для небольших скриптиков, на самом деле. Не хуже lua.

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

Не осилил, да?

И зачем мне осиливать использование массивов на каждый чих, где надо и не надо? Использовать что-то только потому что оно есть, а не потому что требуется - это идиотизм.

Но мне нравится, что ты сравниваешь такую банальную вещь как массивы с потенциальным отстрелом жопы (т.е. unsafe{}).

Т.е. то, что является одним из совершенно нормальных инструментом языка программирования для нормальных людей, для растаманов является «отстрелом жопы»?

Ну в общем-то понятно почему растаманы до сих пор абсолютно ничего полезного на своём языке не написали.

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

Itanium сдох, у остальных двух архитектур на рынке адрес возврата на стеке.

Эльбрус еще не сдох, он просто так пахнет. Правда это не рыночная архитектура.

У RISCV отдельный регистр под это, но это только для текущей функции.

У всех RISC архитектур есть отдельный link регистр для хранения адреса возврата. Но на стек он сохраняется практически всегда. Кроме совсем маленьких функций, что не делают вызовов других функций.

У Intel есть CET расширение на дорогих моделях новых процессоров для защиты от ROP. В ARMv8.3 есть расширение PAC.

jpegqs
()
Ответ на: комментарий от anonymous

Инклуды это не макроязык.

Самый что ни на есть.

Там, условия

Ээээ… без #ifdef это все тоже не имеет смысла. Потому что как ты иначе реализуешь зависимые от архитектуры типы, например?

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

У тебя явные проблемы. Во первых, ifdef никак не относится к копипасте, к которой относится include - проблема раз. Во вторых, если условия(ifdef) уже есть в макроязыке, зачем он просит их ещё раз? И тут два варианта - либо он шиз, либо он просит условия иные нежели твой ifdef(и шиз ты, поскольку не понял о чём речь).

anonymous
()
Ответ на: комментарий от Stanson

Т.е. то, что является одним из совершенно нормальных инструментом языка программирования для нормальных людей, для растаманов является «отстрелом жопы»?

Так не является же. RCE за RCE, 90% уязвимостей — это сишка опять не смогла рассказать программисту, что он инварианты нарушил.

«Безумие — это постоянное повторение одного и того же действия, в еадежде получить другой результат». Люди не умеют программировать на C без RCE, это в принципе невозможно для нашего вида. Любой, кто утверждает обратное — безумец, игнорирующий все доказательства.

anonymous
()