1. C++ / Говнокод #12263

    +18

    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
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    /*
     *      The use of singletons for globals makes globals not
     *      actually be initialized until it is first needed, this
     *      makes the library faster to load, and have a smaller
     *      memory footprint
     */
    
    #define json_global_decl(TYPE, NAME, VALUE)                              \
    class jsonSingleton ## NAME {                                            \
    public:                                                                  \
            inline static TYPE & getValue() json_nothrow {                   \
                    static jsonSingleton ## NAME single;                     \
                    return single.val;                                       \
            }                                                                \
    protected:                                                               \
            inline jsonSingleton ## NAME() json_nothrow : val(VALUE) {}      \
            TYPE val;                                                        \
    }
    
    #define json_global(NAME) jsonSingleton ## NAME::getValue()              \
    
    json_global_decl(json_string, CONST_TRUE, JSON_TEXT("true"));
    json_global_decl(json_string, CONST_FALSE, JSON_TEXT("false"));
    json_global_decl(json_string, CONST_NULL, JSON_TEXT("null"));
    
    /* Использование */
    json_global(ERROR_NULL_IN_CHILDREN)

    Наткнулся на утечку памяти, отловленную Valgrind'ом
    А внутри вот это. И главное, совершенно непонятно, зачем воротить эту свистопляску, если линкеры умеют распознавать "true" по всюду (читаем про ROMability тут: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1396.pdf )
    http://stackoverflow.com/questions/690176/c-c-optimization-of-pointers-to-string-constants

    Сам код отсюда: http://code.google.com/p/wot-replay-parser/source/browse/libjson/Source/JSONGlobals.h

    Запостил: myaut, 10 Декабря 2012

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

    • Это еще чего, я видал в одном фраймверке макрос который генерит по некоу костяку синглетон, так там под дефайном строк 80 шло (экранированых), и ЧТО СУКА ХАРАКТЕРНО - ОБ НИХ ОТЛАДЧИК ПРИ ТРАССИРОВКЕ ВСЯЧЕСКИ СПОТЫКАЕТСЯ.
      Ответить
    • Я так понял это сделано для ленивой отложенной инициализации глобальных объектов при первом обращении. То что в целом некрасиво, то тут язык виноват, но авторы молодцы. Борятся с инструментом. Брат жив. Зависимости нет.
      Надоело писать зеленым цветом.
      Ответить
      • За что я люблю фукнциональщиков - это за то, что слабо понимают как их мегаленивая инициализация реально выполняется на компутере. Стоковые константы поместятся секцию в .rodata, а при старте программы компоновщик ld.so скопирует ее целиком в память. Смысл?
        Ответить
    • Мне интересно, как inline сочетается со объявлением статического объекта внутри блока. Разве тут нет противоречия?
      Ответить
      • это не объект внутри блока, это inline метод
        собственно любой метод, имеющий тело прямо внутри класса - уже inline, независимо от того, статический он или нет
        просто некоторые старые компиляторы в этом не уверены (да, Тарас?)
        Ответить
        • > метод, имеющий тело прямо внутри класса - уже inline
          Да это я знаю, на крестах недавно говнявкать потихоньку начал.
          Мне не ясно, как сочетается объявление статического члена, который должен быть синглетоном (майерсовким), с inline-методом, который будет встраиваться во все места, где используется.
          Ответить
          • inline означает не совсем то, что ты сказал (точнее, не только то, что ты сказал)
            inline означает inline linkage - все инлайновые методы попадают в отдельное место в объектном модуле, и т.к. модулей при линковке, имеющих одни и те же методы, будет несколько (логично, т.к. инлайновые методы обычно попадают в единицу трансляции через хедеры), линкер создаст из них всех одну (1) точку входа в каждый метод (если таковой метод вообще будет нужен как отдельная сущность)
            Ответить
            • Спасибо за пояснение.
              Ответить
            • Т.е. это отдельное место при линковке нескольких объектников обобщается путем выкидывания дублей?
              Мне почему-то сразу вспомнилось про extern template. Вроде в C++11 должно?
              Ответить
              • да, обобщается путем сличения и выкидывания дублей
                в отличие от нормального списка экспорта объектного модуля, где дубли будут считаться ошибкой (symbol/function XXX already defined in other.o)

                > extern template
                ну поглядим как это будет работать на самом деле
                Ответить
        • Да, MSVS2003 не уверен и кукарекает, если один и тот же класс с неинлайном объявлен в разных цпп.
          Ответить

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