- 1
- 2
- 3
- 4
- 5
- 6
- 7
#define LengthOfArrayInternal(a)(sizeof(a)/sizeof(a[0]))
#define is_array(x) _Generic((x), typeof((x)[0])[LengthOfArrayInternal(x)]:1, default: 0)
#define COMPILE_TIME_ASSERT(expr) char constraint[expr]
#define length_of_array(a) ({COMPILE_TIME_ASSERT(is_array(a)); LengthOfArrayInternal(a)})
Неужели день прошел без того, чтобы Гумно не запостило очередной херни.
Знать длину массива и при этом не заводить константу под нее нужно только в одном случае - инициализированный массив неизвестной длины: А этих случаев во-первых не так много, во-вторых если он все-таки будет перепилен на указатель, тебе все равно придется где-то хранить длину, и втыкать ее вместо sizeof().
В соседнем треде
http://govnokod.ru/12108#comment160879
, из которого вырос этот тред, сказали, что создатели google chrome используют плохоработающий COUNT_OF. Скажи это им.
http://ideone.com/N9FpVB Для массива &a и a равны, а у всех остальных типов нет. Проверка надежная, но, к сожалению, в райнтайме.
и, кстати, если значение переменной совпадает с адресом, это может быть и не массив, а случайное совпадение :)
http://ideone.com/WPiT43
Тестил на gcc с -Wall -Wextra -pedantic -std=c89 и до кучи на -ansi, поэтому скорее всего должно заработать и на визуалке и других компиляторах.
P.S. В режиме с++ этот макрос использовать нельзя.
P.P.S. В хидерах тоже использовать нельзя. Если очень хочется - нужно __LINE__ поменять на __COUNTER__, который не кроссплатформа.
P.S. Разве что найти какую-то хрень, которая не будет компилиться внутри выражений в зависимости от какого-то параметра...
Первое, что приходит в голову - ошибка компиляции при преобразовании типов, но как заставить макрос в зависимости от условия вернуть переменную нужного типа?
upd: А впрочем я кажется знаю.
http://ideone.com/N7MZ4R
За неимением лучшего.
http://ideone.com/j2dVoo
http://ideone.com/grht3g
К сожалению эта реализация это не делает. Можно конечно энум использовать для взврата значения, но тогда она не сможет выдавать длину массива времени выполнения.
- длина времени выполнения
typeof и statement in expression - gcc extension
Сишка - отличный язык. Да, компилятор делает для тебя не так много работы, зато язык по большей части очень прост и не перегружен абстракциями и парадигмами.
Он для людей, которые решают задачи, а не школьников, которые хвалятся на геймдеве очередным крестовысером.
Хотя и кресты можно использовать правильно, если подойти к этому с головой.
Видать тоже крестолюб.
А я этого и не отрицал.
Ты крестолюб.
Я за всю жизнь не то что-бы кинуть, даже случайно уронить флешку с крестопримером не смог. А ты говоришь кидал.
Например
Да ну. Если не изменяет память можно вообще libc отстегнуть и писать на голых syscall'ах/winapi.
А рантайм крестов в гцц это libstdc++, по дефолту он не пристегивается.
а что, зеленым на говнокоде теперь выделяется асм?
> точка с запятой и до конца строки