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

    +137.6

    1. 1
    w = (GtkWidget*)(*((int*)(lw->data)));

    Объект для медитаций

    Запостил: mutanabbi, 13 Февраля 2010

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

    • Откуда в Си объекты? O_o
      :D
      Ответить
    • Объект для медитаций в Си. Интересно. Буду копать. :D
      Ответить
    • Да что тут медитировать-то, секунды 3-4 всего
      Ответить
      • Привести к указателю на int, чтобы тут же разыменовать и привести полученный int к указателю на GtkWidget. Бессмысленность всего сущего прочувствована
        Ответить
        • Ненене, Вы, видимо звездочки не заметили. Привести к указателю на инт, взять число по указателю, а затем уже енто дело привести к указателю на на GtkWidget.
          Ответить
          • Это называется разыменование указателя. Читаем еще раз.
            Ответить
            • Да, с терминологией у меня хреново, простите за тупизну.
              Не для того чтобы задеть, а ради того чтобы научиться, вопрос:
              как в данном случае правильно преобразовать данные, хранящиеся в ячейке на которую указывает элемент структуры data, к указателю на GtkWidget?
              Ответить
              • Лучший способ - не использовать касты вообще.
                Если жизненно необходимо преобразование типов, то использовать явные преобразования в стиле C++ (если говорим о нем). В любом случае тут должно быть приведение к указателю на указатель судя по контексту. А уж static_cast или reinterpret_cast это будет - зависит от типа поля data. Что-то в духе
                w = *static_cast<GtkWidget**>(lw->data);
                Ответить
                • Я то думал мы о чистом С (без плюсов). В этом случае, с моей точки зрения, если элемент data имеет тип void*, то данное преобразование можно объяснить. В частности преобразование к int* может быть необходимо чтобы потом прочитать число нужной разрядности.
                  Ответить
                  • если Си
                    w = *(GtkWidget**)(lw->data);
                    Преобразование к инту не нужно. Кастовать указатели в интегральные типы и обратно очень плохая практика.
                    Ответить
                    • Да, Вы правы, спасибо за науку.
                      Ответить
                    • Да, буквально сейчас на работе этим занимаюсь, чищу такие хакерские гнусные приведения к инту и обратно.
                      Ответить
                      • К тому же приведение интов к указателям и наоборот есть не кросс-платформенно, где-то пойдут глюки и аффтар не сразу проссыт
                        Ответить
        • "*(int*)" укоротит/удлиннит численное значение до разрядности int-а.

          Возможно "data" имеет тип "char", и чтобы в "w" положить нужное значение поинтера (для 32-битных систем, 32-битное значение, что соотвествует int-у или, допустим, long-у), сначала приказываем считывать значение как int, а только потом ложим в w. Тут есть смысл, разве что не кроссплатформено это всё (хотя бы "long" использовали, хотя это было бы тоже убого).
          Ответить
          • Ах да, я ж забыл написать самое любимое комменто-читателями.

            Правильным вариантом было бы например:
            w = *(GtkWidget**)lw->data;
            Ответить
            • Млин, оказалось уже и так отвечено(
              Ответить
            • По-моему, правильно будет всё-таки использовать стандатные макросы:
              w = GTK_WIDGET(*lw->data);
              Ответить

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