1. Си / Говнокод #20071

    −47

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    static struct frame rx_frame = {
    	.data = rx_buffer,
    	.sz = sizeof(rx_buffer)
    };
    
    ...
    
    где-то в том же модуле:
    struct frame *task_communication_receive_frame(void)
    {
    memset(rx_frame, 0, sizeof(rx_frame));
    ...
    }

    Действительно, чёй-то какая-то срань принимается

    Запостил: MiD, 25 Мая 2016

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

    • >>>
      static struct frame rx_frame = {
      	.data = rx_buffer,
      	.sz = sizeof(rx_buffer)
      };

      Поясните плз за синтаксис - что это такое?
      Ответить
      • C99. https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
        Ответить
        • Another syntax that has the same meaning, obsolete since GCC 2.5, is ‘fieldname:’, as shown here:
          struct point p = { y: yvalue, x: xvalue };
          А ведь устаревший синтаксис похож на JSON.


          To initialize a range of elements to the same value, write ‘[first ... last] = value’. This is a GNU extension. For example,
          int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
          Круто! Диапазоны почти паскалевского синтаксиса. Ещё бы в свитч-кейс их завезли...

          А вот это выглядит ужасно:
          struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
          Ответить
          • > А ведь устаревший синтаксис похож на JSON.

            мне он больше нравился. где-то плавало весьма расплывчатое объяснение почему ISO решил в конце синтакс с точкой стандартизировать.
            Ответить
            • Чтобы не путать с меткой. Вдруг захочешь сделать goto в середину инициализации структуры, а синтаксис запрещает.
              Ответить
          • >Круто! Диапазоны почти паскалевского синтаксиса. Ещё бы в свитч-кейс их завезли...
            В GCC завезли: http://ideone.com/oql1jt
            Ответить
            • Прикольно, не знал, что так можно. А ещё какую нить магию сможешь показать, Дэвид Блэйн?)
              Ответить
              • Неа, меня самого этому научил семиклассник.
                Ответить
            • фу
              а как же ANSI C?
              Ответить
              • В то время как плюсы штампуют новые стандарты, сишники до сих пор живут 89 годом...
                Ответить
                • А как же C99 и C11?
                  Ответить
                  • C99 в 9 раз лучше чем C11 или старше на 88 версий?
                    Ответить
                • ой ну нет
                  давно уже можно делать VLA, декларить переменные не сверху блока, давно уже есть wchar итд
                  Ответить
                  • VLA - блядское говно, на самом деле. Единственное его применение без обязательного выстрела в ногу - маллочить многомерные массивы.
                    Ответить
                    • Не маллочить а аллакалочить же. динамически двтгать стек
                      Ответить
                      • Динамически двигать стек - почти всегда хуёвая идея. Я имел в виду вот это
                        int (*mdim)[M][L] = (int (*)[M][L]) malloc(sizeof(int)*N*M*L);
                        Ответить
                        • почему хуевая?

                          имхо, если можно обойтись без динамической кучи, то лучше без нее обойтись

                          другой вопрос что в стек можно случайно захуячить 20 гигабайт и сделать плохо
                          Ответить
                          • > почему хуёвая
                            Никогда стек не рвался от аллоки, вла или просто большого массива?
                            Ответить
                            • рвался!

                              потому и было сказано: "захуячить 20 гигабайт"

                              Но если я _точно_ знаю что там лежит массив из десяти интов, то нафиг мне беспокоить менеджера куч?
                              С другой стороны я могу и статически определить массив на 10 интов без VLA
                              Ответить
                              • Вот именно! Когда ты знаешь лимиты - обычный массив сойдёт. А когда не знаешь - и вла нельзя юзать.
                                Ответить
                                • эх

                                  выходит, динамическое управление стеком вообще не нужно?
                                  Ответить
                                • Что-то подумалось вот про что:
                                  void foo(const size_t sz)
                                  {
                                      uint8_t foo_buf[sz];
                                      ....
                                  }

                                  В этом случае, я так понимаю, остаётся на совести программиста, сколько будет сожрано памяти на стеке, т.е. тоже говно и так делать нельзя?
                                  Ответить
                                  • Ну это же и есть тот самый VLA.
                                    Ответить
                                  • Да, на совести программиста. Да, говно. Да, нельзя.

                                    Хуже можно было сделать, только используя int вместо size_t. VLA отрицательного размера тоже можно сделать.
                                    Ответить
                                    • > VLA отрицательного размера тоже можно сделать.
                                      ***! *****!
                                      А что в этом случае будет? Конец стека подвинется обратно и вызов вложенных функций затрёт локальные переменные? Размер кастанётся к беззнаковому числу?
                                      Ответить
                                      • Конец стека двигается обратно. Локальные переменные коллера так затереть можно, но это уже мелочи. Ключевая проблема в том, что так легко затереть адрес возврата.

                                        Справедливости ради замечу, что если компилятор может доказать, что размер отрицательный, он выдаёт ошибку.
                                        Ответить
            • круто
              Ответить
    • а вызывают типа из другого модуля?
      Ответить
      • Инициализируется структура с указателем на буфер и его размером. memset область памяти rx_frame заполняет нулями, тем самым затирая адрес буфера, на который указывает указатель
        Ответить

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