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

    0

    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
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    // channel.h
    
    #pragma once
    
    namespace AMQP {
    
    class Channel
    {
    private:
        std::shared_ptr<ChannelImpl> _implementation;
    
    public:
        Channel(Connection *connection) : _implementation(new ChannelImpl()) 
        {
            // attach the connection to the channel
            _implementation->attach(connection);
        }
        
        Channel(const Channel &channel) = delete;
    
        virtual ~Channel() 
        {
            // close the channel (this will eventually destruct the channel)
            _implementation->close();
        }
    
        //...
    };
    
    // ---------------------------------------------------------
    // amqpcpp.h
    
    /**
     *  AMQP.h
     *
     *  Starting point for all includes of the Copernica AMQP library
     *
     *  @documentation public
     */
    
    #pragma once
    
    // base C++ include files
    #include <vector>
    #include <string>
    #include <memory>
    #include <map>
    //...
    
    // base C include files
    #include <stdint.h>
    #include <math.h>
    
    // forward declarations
    #include <amqpcpp/classes.h>
    
    // utility classes
    #include <amqpcpp/endian.h>
    #include <amqpcpp/buffer.h>
    #include <amqpcpp/bytebuffer.h>
    //...
    
    // amqp types
    #include <amqpcpp/field.h>
    #include <amqpcpp/numericfield.h>
    #include <amqpcpp/decimalfield.h>
    #include <amqpcpp/stringfield.h>
    //...
    
    // envelope for publishing and consuming
    #include <amqpcpp/metadata.h>
    #include <amqpcpp/envelope.h>
    #include <amqpcpp/message.h>
    
    // mid level includes
    #include <amqpcpp/exchangetype.h>
    #include <amqpcpp/flags.h>
    #include <amqpcpp/callbacks.h>
    #include <amqpcpp/deferred.h>
    #include <amqpcpp/deferredconsumer.h>
    #include <amqpcpp/deferredqueue.h>
    #include <amqpcpp/deferreddelete.h>
    #include <amqpcpp/deferredcancel.h>
    #include <amqpcpp/deferredget.h>
    #include <amqpcpp/channelimpl.h>
    #include <amqpcpp/channel.h>
    //...

    https://github.com/CopernicaMarketingSoftware/AMQP-CPP

    Запостил: scp, 23 Декабря 2015

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

    • pimpl, да не совсем.
      Ответить
    • Мне больше всего понравились хэдеры в каталоге include, которые на самом деле нельзя инклюдить, а нужно везде инклюдить суперинклюд amqpcpp.h, включающий в себя все хэдеры из include. Очень хитрый ход, чтобы во время компиляции можно было успеть посражаться на мечах, построить дом, родить сына и все такое.
      А хэдеры, похоже, писал джавист, который не знал, что в крестах можно оставить объявление неабстрактного метода без реализации, а реализацию писать в cpp.
      Интересно, в Copernica весь софт такой?
      Ответить
      • зато если начальник спрашивает "а какого черта ничего не делаешь?" всегда можно ответить "компилируется"
        Ответить
      • "Мне больше всего понравились хэдеры в каталоге include, которые на самом деле нельзя инклюдить, а нужно везде инклюдить суперинклюд amqpcpp.h, включающий в себя все хэдеры из include. "

        Раньше такое делалось для precompiled headers. И все компилировалось очень даже быстро. https://en.wikipedia.org/wiki/Precompiled_header

        Текущего статуса фичи (precompiled headers) не знаю: раньше это работало надежно только под MSVC, а я в те времена уже на линух пересел, и GCC этого в те времена не поддерживал.

        Все через один хидер нужно для того что бы гарантировать стабильный порядок включения, т.к. хидеры могут зависеть от дефайнов определенных в других хидерах.
        Ответить
        • > GCC этого в те времена не поддерживал
          3.4 and newer, 2006 год
          Ответить
          • последний раз когда я работал на большом С++ проекте под линухом и эксклюзивно с GCC было в 2002-4 годах. проект был на GCC версиях 2.95 - 3.2.

            так задумываясь, на последних проектах (абстрагируясь от компилера) добавить поддержку для pch было бы крайне не тривиально, из-за мешанины старго говна и скриптов в мэйкфайлах. и так как все про фичу уже давно забыли, то никто и не спрашивает. на моем текущем проекте билд система вообще даже тривиальнвй инкрементал не умеет - билдид всегда все по новой.

            ЗЫ еще один голос в пользу cmake: https://github.com/sakra/cotire
            Ответить
            • фу быть таким старым
              Ответить
              • пиздец подкрался не заметно.

                на предыдущей работе когда начинал - был самым молодым.

                на новой работе начал год назад - самый старый.
                Ответить
        • > гарантировать стабильный порядок включения
          Если у тебя результат зависит от порядка подключения хедеров - это хуёвые и несамодостаточные хедеры. Самая жопа всех этих stdafx.h в том, что из-за них через пару лет почти все хедеры становятся хуёвыми и несамодостаточными. Из-за чего их по-другому уже никак не подключить, и таких хедеров становится всё больше и больше... Замкнутый круг.
          Ответить
          • > > гарантировать стабильный порядок включения

            > Если у тебя результат зависит от порядка подключения хедеров - это хуёвые хедеры.

            у меня?? они такие у всех. ещё ни одного проекта чистого не видел.(*) не говоря уже о системных хидерах. или компилерных хидерах. (последний раз когда заглядывал, NULL условно в трех разных местах определялся.)

            (*) и щас подымутся кучи народов, и начнут себя бить пяткой в грудь что их проект не такой. а на самом скорее всего именно такой, потому без целенаправленого тестирования, эти проблемы находятся только когда начинаешь писать нечтно новое с нуля, без копи-пасты boiler-plate'а из других частей проекта. что случает крайне редко, почему народ и думает что у них на проекте все в порядке.
            Ответить
            • > что их проект не такой
              Такой, к сожалению. Подумываем на следующем рефакторинге убрать #include "stdafx.h" из cpp'шников и добавлять его через опцию компилятора, чтобы можно было её изредка отключать и смотреть, в каких хедерах запороли автономность.
              Ответить
              • > > что их проект не такой

                > Такой, к сожалению.

                я на самом деле этой проблеме внимания почти не уделяю. если вижу - фикшу. но целенаправленно еще ни разу не тестировал. потому что редко в большую проблему выливается.

                самая большая проблема которую видел (деталей уже не помню) была в С++ с темплейтами и операторами. объявления какого то типа не хватало, но компилятор объявления темплейта сжевывал. в результате, на половине проекта оператор работал (где объявление типа включалось перед объявлением оператора), на другой вылетал с загадочными ошибками (с 10-ти строчными сообщениями об ошибках). да и нашел я это только случайно, когда в объектнике в символьной таблице кривой темплейт заметил. проблема была древняя - но ни какого грандиозного всплеска от ее решения на проекте не произошло.
                Ответить
            • > эти проблемы находятся
              Да там не всё так страшно. Дофига хедеров имеют соответствующий им cpp'шник. Вот в нём первой строчкой инклудишь соответствующий хедер. И проблема с самодостаточностью решена раз и навсегда (если, конечно, stdafx.h отключаемый).

              В общем-то даже для header-only либ можно сделать/сгенерить фейковые cpp'шки, состоящие из одного #include "header.h", которые в отдельной конфигурации билдятся чисто для проверки автономности.
              Ответить
              • проблемы с нормальными хидер/сорс парами локализованы, и находятся достаточно быстро либо при код ревью, либо при нормальном использовании.

                больше всего проблем видел с глобальными хидерами.

                тот же NULL и любимый "stddef.h" - я несколько лет на С/С++ писал, а про этот хидер не знал, потому что почти нигде напрямую не включается. всегда либо глобально, либо через побочных эффект другого инклюда. а когда начинаешь писать с нуля - валится с ошибкой что NULL не определен...
                Ответить
                • пользуйтесь nullptr. А вообще, все хедеры должны инклюдить всё, от чего они зависят. В идеале.
                  Ответить
    • Не понял, на кой хрен тут шаред.
      Пытаюсь подумать. Допустим, в аттаче этот коннекшон тоже запонимает указатель на этот чанел_импл. А когда класс дохнет, то остаётся разаттаченный чанел_импл, которого помнит кто-то ещё зачем-то.
      Не, всё равно не понял.
      Ответить
      • Это говнокод, поэтому и шаред.
        Ответить
      • Потому что если рабы ГЦ не осилили грамотную работу с заголовочными файлами и forward declarations, то и грамотного использования концепции владения ждать не стоит.
        Ответить

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