Няшная / Говнокод #12133 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 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)})

Определение длины массива. gcc и с11 only.
Говно как известно рождается в споре:
http://govnokod.ru/12108#comment160631

Запостил: LispGovno LispGovno, (Updated )

Комментарии (48) RSS

  • с11 компилятора у меня нет, так что ещё нужно проверить
    Ответить
  • Странно. А я уж подумал - неужели?
    Неужели день прошел без того, чтобы Гумно не запостило очередной херни.
    Ответить
    • ты так говоришь, как будто у тебя есть реализация понадежнее или покороче, не считая заведения отдельной константы под длину
      Ответить
      • Ты так говоришь, как-будто это нужно.

        Знать длину массива и при этом не заводить константу под нее нужно только в одном случае - инициализированный массив неизвестной длины:
        int s[] = {1,2,3,4,5};
        А этих случаев во-первых не так много, во-вторых если он все-таки будет перепилен на указатель, тебе все равно придется где-то хранить длину, и втыкать ее вместо sizeof().
        Ответить
        • >Ты так говоришь, как-будто это нужно.
          В соседнем треде
          http://govnokod.ru/12108#comment160879
          , из которого вырос этот тред, сказали, что создатели google chrome используют плохоработающий COUNT_OF. Скажи это им.
          Ответить
          • Вот такая штука еще сегодня попалась:
            (void*)&(a) == (void*)(a)
            Для массива &a и a равны, а у всех остальных типов нет. Проверка надежная, но, к сожалению, в райнтайме.

            http://ideone.com/N9FpVB
            Ответить
            • Интересный способ. Уж лучше чем ничего. Интересно, а в крестах это соблюдается? Пока вижу несоблюдение этого правила только при перегрузке оператора взятия адреса.
              Ответить
            • интересно, а можно ли реализовать это функцией, а не макросом?
              и, кстати, если значение переменной совпадает с адресом, это может быть и не массив, а случайное совпадение 🙂
              http://ideone.com/WPiT43
              Ответить
          • Проверка во время компиляции: http://ideone.com/5sJmTR.

            Тестил на gcc с -Wall -Wextra -pedantic -std=c89 и до кучи на -ansi, поэтому скорее всего должно заработать и на визуалке и других компиляторах.

            P.S. В режиме с++ этот макрос использовать нельзя.
            P.P.S. В хидерах тоже использовать нельзя. Если очень хочется - нужно __LINE__ поменять на __COUNTER__, который не кроссплатформа.
            Ответить
            • В компил-тайме оно работает, только вот не впихнуть его в макрос length_of_array из-за того, что это declaration, как я писал ниже. 🙁
              Ответить
              • Да по-нормальному походу никак. Кроме как гццизмом с блоками внутри выражений.

                P.S. Разве что найти какую-то хрень, которая не будет компилиться внутри выражений в зависимости от какого-то параметра...
                Ответить
  • Ох уж эти крестолюбы-псевдофункциональщики...
    Сишка - отличный язык. Да, компилятор делает для тебя не так много работы, зато язык по большей части очень прост и не перегружен абстракциями и парадигмами.
    Он для людей, которые решают задачи, а не школьников, которые хвалятся на геймдеве очередным крестовысером.

    Хотя и кресты можно использовать правильно, если подойти к этому с головой.
    Ответить
    • Почему меня уже в крестолюбы записали, лол? Я самый настоящий функциональщик.
      Ответить
        • Ну и ты зашквариться успел крестопримерами.
          Видать тоже крестолюб.
          Ответить
          • Это ничего не значит. Я вот сколько крестопроблем повидал, а в крестолюбии меня обвинить трудно.
            Ответить
        • >Крестопримеры кидал - кидал.
          Я за всю жизнь не то что-бы кинуть, даже случайно уронить флешку с крестопримером не смог. А ты говоришь кидал.
          Ответить
      • истинно говорю тебе - трижды отречешься от крестов, прежде чем прокукарекает петушок
        Ответить
    • А я считаю, в сишку пора уже нормально добавить рантйам в компилятор.
      Например
      #define fACT(x) _Do
      {
        if (_Isconst(x)) 
        {
          int r=x; while(--x) r*=x;
          _Generate("$r");       
        } else _Generate ("int r=x; while(--x) r*=x; return x;");
      }
      Ответить
      • Если честно лучше не надо. Здесь оно выглядит как ослу пятая нога. Так получится "Паладин 2".
        Ответить
        • Если честно, то сишка - лучший кандидат (после лоловэма) на добавление рантайма в компилятор. Потому что нет ничего лишнего, всё, что нужно, можно добавить средствами языка, правда, с уёбищным синтаксисом и полным отсутствием поддержки со стороны среды.
          Ответить
          • Рантайм современной сишки так разбух. Там помоему в gcc сейчас даже рантайм крестов в сишку пихают. Поэтому не взлетит.
            Ответить
            • > Там помоему в gcc сейчас даже рантайм крестов в сишку пихают.
              Да ну. Если не изменяет память можно вообще libc отстегнуть и писать на голых syscall'ах/winapi.

              А рантайм крестов в гцц это libstdc++, по дефолту он не пристегивается.
              Ответить
              • Ну ты померь размер программы на сишке gcc и на крестах gcc. И сравни размер сишной программы на gcc там какого-нибудь мохнатого года и современную сишную на gcc. Разрослось, врагу не пожелаешь.
                Ответить
                  • А такое, что писать рантайм для языка на языки с большим рантаймом - моветон. Смотри компилятор D, например.
                    Ответить
                    • Я не про то, чтобы добавить что-то в рантайм сишки, а наоборот, добавить рантайм в компилятор. Гумно, ты опять отвечаешь невпопад?
                      Ответить
                      • А ты опять спрашиваешь не в поп ад? Соберись. Подумай немного. Я верю в тебя.
                        Ответить
            • Я не про то, чтобы добавить что-то в рантайм сишки, а наоборот, добавить рантайм в компилятор. Гумно, ты опять отвечаешь невпопад?
              Ответить
              • Я про тоже самое. Ну а если ты "не понял юмора" (см пост ниже), то я ничего не могу c тобой поделать. Все вопросы к своим родителям и учителям.
                Ответить
          • Ну и по моему лолиВм более лоли. По этому подходит больше.
            Ответить
      • Лол точка с запятой и до конца строки зелёные, мой код что, приняли за асм?
        Ответить
  • Кстати, может кто видит, как избавится от gcc extension statement and declaration in expression? Мне пришлось его применить, тк по сути COMPILE_TIME_ASSERT - declaration. Всё-таки typeof рано или поздно появится в стандарте. Это лишь вопрос времени.
    Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8