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

    −1

    1. 1
    2. 2
    3. 3
    Если у меня есть приватный метод, то зачем мне его объявлять в .h-файле?
    Хочу только в .cpp написать вспомогательный метод и только там его использовать.
    А вынужден копипастить сигнатуру ещё и в .h.

    3_dar, 10 Сентября 2021

    Комментарии (151)
  2. C++ / Говнокод #27621

    +4

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    struct Foo {
    };
    
    struct Bar {
        int x[0];
    };

    https://ideone.com/upuoOg

    Какая консистентность )))

    bormand, 27 Августа 2021

    Комментарии (88)
  3. C++ / Говнокод #27619

    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
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    const int sum(int a, int b){
        return a+b;
    }
    
    int a(int x)
    {
        const std::function<int(int)> sum4 = std::bind(sum,_1, 4);    
        return sum4(123);
    }
    
    int b(int x)
    {
        puts("bagor");    
        const std::function<int(int)> sum4 = std::bind(sum,_1, 4);    
        return sum4(123);
    }
    
    int c(int x)
    {
        const std::function<int(int)> sum4 = std::bind(sum,_1, 4);    
        puts("bagor");    
        return sum4(123);
    }
    
    // Функции a и b нормально инлайнятся. Ассемблерный выхлоп:
    
    sum(int, int):                               # @sum(int, int)
            lea     eax, [rdi + rsi]
            ret
    a(int):                                  # @a(int)
            mov     eax, 127
            ret
    b(int):                                  # @b(int)
            push    rax
            mov     edi, offset .L.str
            call    puts
            mov     eax, 127
            pop     rcx
            ret
    
    //А вот int c(int x)
    c(int):                                  # @c(int)
            push    rbx
            sub     rsp, 32
            mov     edi, 16
            call    operator new(unsigned long)
            mov     rbx, rax
            mov     qword ptr [rax], offset sum(int, int)
            mov     dword ptr [rax + 8], 4
            mov     qword ptr [rsp], rax
            mov     qword ptr [rsp + 24], offset std::_Function_handler<int (int), std::_Bind<int const (*(std::_Placeholder<1>, int))(int, int)> >::_M_invoke(std::_Any_data const&, int&&)
            mov     qword ptr [rsp + 16], offset std::_Function_handler<int (int), std::_Bind<int const (*(std::_Placeholder<1>, int))(int, int)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)
            mov     edi, offset .L.str
            call    puts
            mov     esi, dword ptr [rbx + 8]
            mov     edi, 123
            call    qword ptr [rbx]
            mov     ebx, eax
            mov     rax, qword ptr [rsp + 16]
            test    rax, rax
            je      .LBB3_3
            mov     rdi, rsp
            mov     rsi, rdi
            mov     edx, 3
            call    rax
    .LBB3_3:
            mov     eax, ebx
            add     rsp, 32
            pop     rbx
            ret
            mov     rdi, rax
            call    __clang_call_terminate
            mov     rbx, rax
            mov     rax, qword ptr [rsp + 16]
            test    rax, rax
            je      .LBB3_6
            mov     rdi, rsp
            mov     rsi, rdi
            mov     edx, 3
            call    rax
    .LBB3_6:
            mov     rdi, rbx
            call    [email protected]
            mov     rdi, rax
            call    __clang_call_terminate
    __clang_call_terminate:                 # @__clang_call_terminate
            push    rax
            call    __cxa_begin_catch
            call    std::terminate()
    std::_Function_handler<int (int), std::_Bind<int const (*(std::_Placeholder<1>, int))(int, int)> >::_M_invoke(std::_Any_data const&, int&&): # @std::_Function_handler<int (int), std::_Bind<int const (*(std::_Placeholder<1>, int))(int, int)> >::_M_invoke(std::_Any_data const&, int&&)
            mov     rax, qword ptr [rdi]
            mov     rcx, qword ptr [rax]
            mov     edi, dword ptr [rsi]
            mov     esi, dword ptr [rax + 8]
            jmp     rcx                             # TAILCALL
    std::_Function_handler<int (int), std::_Bind<int const (*(std::_Placeholder<1>, int))(int, int)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation): # @std::_Function_handler<int (int), std::_Bind<int const (*(std::_Placeholder<1>, int))(int, int)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)

    Решил попробовать std::bind.

    https://godbolt.org/z/eW5eT5oj4

    3.14159265, 27 Августа 2021

    Комментарии (86)
  4. C++ / Говнокод #27614

    +1

    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
    struct file_id
    {
        uint64_t        persistent;
        uint64_t        volatile_;
    
        static const size_t RAW_LENGTH  = 16;
        operator std::string() const
        { return std::string(reinterpret_cast<const char*>(&persistent), RAW_LENGTH); }
    
        // Операторы для использования file_id в качестве ключа map и 
        // unordered_map
        struct hash
        {
            std::size_t operator()(const ntdec_smb2_file_id& file_id) const
            {
                std::string s_file_id = file_id;
                std::hash<std::string> hasher;
                return hasher(s_file_id);
            }
        };
    
        bool operator == (const ntdec_smb2_file_id& other)
        {
            return std::string(*this) == std::string(other);
        }
    
        bool operator < (const ntdec_smb2_file_id& other)
        {
            return std::string(*this) < std::string(other);
        }
    
        bool operator > (const ntdec_smb2_file_id& other)
        {
            return std::string(*this) > std::string(other);
        }
    };

    operator std::string тоже UB?

    YpaHeLI_, 24 Августа 2021

    Комментарии (11)
  5. C++ / Говнокод #27568

    +2

    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
    // https://github.com/seanbaxter/circle/blob/master/examples/README.md#tldr
    // ...
    // Circle's primary syntactic element is the @meta keyword, which runs the prefixed statement
    // during source translation (or during template instantiation in dependent contexts).
    
    // https://github.com/seanbaxter/circle/blob/master/examples/README.md#same-language-reflection
    // duff1.cxx
    
    void duff_copy1(char* dest, const char* source, size_t count) {
      const char* end = source + count;
      while(size_t count = end - source) {
        switch(count % 8) {
          case 0: *dest++ = *source++; // Fall-through to case 7
          case 7: *dest++ = *source++; // Fall-through to case 6...
          case 6: *dest++ = *source++;
          case 5: *dest++ = *source++;
          case 4: *dest++ = *source++;
          case 3: *dest++ = *source++;
          case 2: *dest++ = *source++;
          case 1: *dest++ = *source++;
          break;
        }
      }
    }
    
    // Reproduced above is a simplified version of Duff's device, an infamous memcpy function designed
    // to reduce the amount of branching in the operation. (The loop is optimally interleaved with the switch,
    // but I'm trying to illustrate some other points and don't want to add to the confusion.) Once we enter the
    // switch, perform an assignment and unconditionally progress to the next case statement. This algorithm
    // cries out for automation. The case statements have indices that run from 8 down to 1, modulo 8. Can we give it the Circle treatment?
    
    // duff2.cxx
    
    void duff_copy2(char* dest, const char* source, size_t count) {
      const char* end = source + count;
      while(size_t count = end - source) {
        switch(count % 8) {
          @meta for(int i = 8; i > 0; --i)
            case i % 8: *dest++ = *source++;
          break;
        }
      }

    Но гомоиконности таким подкостыливанием вы естественно не добавите!

    j123123, 14 Августа 2021

    Комментарии (21)
  6. C++ / Говнокод #27561

    +1

    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
    QSqlQuery& SQLConnect::get()
    {
        if ( makeConnection() ) {
            query = QSqlQuery(mDb);
            return query;
        }
        QSqlQuery empty;
        return empty;
    }
    
    bool SQLConnect::makeConnection()
    {
       mDb = SQLConnectPool::Instance().get();
       return true;
    }

    Раньше компилилось и не замечал, а тут на новом компиляторе начал кидать ошибки и решил посмотреть, что же там напроектировали

    avk17, 14 Августа 2021

    Комментарии (12)
  7. C++ / Говнокод #27536

    +1

    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
    class Solution {
    public:
        std::vector<std::vector<int>> diagonalSort(std::vector<std::vector<int>> & mat) {
            if (!mat.size()) return mat;
            
            const size_t rl = mat[0].size();
            const size_t cl = mat.size();
            
            sort(mat, rl, cl, 0, 0);
            for (size_t i = 1; i < rl; ++i) {
                sort(mat, rl, cl, 0, i);
            }
            for (size_t i = 1; i < cl; ++i) {
                sort(mat, rl, cl, i, 0);
            }
            
            return mat;
        }
    private:
        void sort(std::vector<std::vector<int>> & mat, size_t rl, size_t cl, size_t i, size_t j) {
            const size_t len = std::min(rl - j, cl - i);
            const size_t endj = j + len;
            const size_t endi = i + len;
            std::sort(diag_iter<false>{&mat, i, j}, diag_iter<false>{&mat, endi, endj});
        }
        
        template <bool isConst>
        class diag_iter {
            std::vector<std::vector<int>> *base;
            size_t i, j;
            using T = int;
        public:
            using iterator_category = std::forward_iterator_tag;
            using difference_type   = std::ptrdiff_t;
            using value_type        = T;
            using pointer           = T*;
            using reference         = typename std::conditional<isConst, const T&, T&>::type;
            diag_iter(std::vector<std::vector<int>> *base, size_t i, size_t j) : base(base), i(i), j(j) { }
            diag_iter(const diag_iter&) = default;
            diag_iter& operator=(const diag_iter&) = default;
            ~diag_iter() = default;
            reference operator*() const { return (*base)[i][j]; }
            diag_iter& operator++() { i++; j++; return *this; }
            friend bool operator== (const diag_iter& a, const diag_iter& b) { return a.i == b.i && a.j == b.j; };
            friend bool operator!= (const diag_iter& a, const diag_iter& b) { return !(a == b); };
            pointer operator->() const { return &(this->operator*()); }
            diag_iter operator++(int) { diag_iter tmp = *this; ++(*this); return tmp; }
            diag_iter() = default;
            diag_iter& operator--() { i--; j--; return *this; }
            diag_iter operator--(int) { diag_iter tmp = *this; --(*this); return tmp; }
            diag_iter& operator+=(difference_type n) { i += n; j += n; return *this; }
            friend diag_iter operator+(diag_iter it, difference_type n) { return it += n; }
            diag_iter& operator-=(difference_type n) { i -= n; j -= n; return *this; }
            diag_iter operator-(difference_type n) const { return diag_iter(*this) -= n; }
            friend difference_type operator-(const diag_iter& a, const diag_iter& b) { return (b.j * b.base->size() + b.i) - (a.j * a.base->size() + a.i); }
            reference operator[](difference_type n) const { return *(*this + n); }
            friend bool operator<(const diag_iter& a, const diag_iter& b) { return b - a > 0; }
            friend bool operator>(const diag_iter& a, const diag_iter& b) { return b < a; }
            friend bool operator>=(const diag_iter& a, const diag_iter& b) { return !(a < b); }
            friend bool operator<=(const diag_iter& a, const diag_iter& b) { return !(a > b); }
        };
    };

    https://leetcode.com/problems/sort-the-matrix-diagonally/

    Сортировка через итераторы оказалась примерно в три раза медленнее, чем через копирование в вектор, сортировку его и копирование обратно.

    grillow1337, 25 Июля 2021

    Комментарии (18)
  8. C++ / Говнокод #27533

    +1

    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
    #include <iostream>
    #include <functional>
    
    #define STD_FUNCTION(a, ...) typeof( a (*) __VA_ARGS__ )
    
    template<typename T>
    T do_op_t(T a, T b, STD_FUNCTION(T,(T,T)) op)
    {
      return op(a,b);
    }
    
    template
    <
    
      typename T,
    
      STD_FUNCTION(
        T,
        (
          T,T,
          STD_FUNCTION(
            T,
            (T,T)
          )
        )
      ) F1,
    
      STD_FUNCTION(
        T,
        (T,T)
      ) F2
    
    >
    T do_op_spec(T a, T b)
    {
      return F1(a, b, F2);
    }
    
    int add(int a, int b) { return a + b; }
    
    int mul(int a, int b) { return a * b; }
    
    std::function<int(int,int)> fnc = \
      do_op_spec\
      <
        int,
        do_op_t<int>,
        add
      >;
    
    int main()
    {
      std::cout << do_op_t<int>(9, 9, add) << "\n";
      std::cout << do_op_t<int>(9, 9, mul) << "\n";
      std::cout << do_op_spec<int, do_op_t<int>,add>(9,9)  << "\n";
      std::cout << do_op_spec<int, do_op_t<int>,mul>(9,9)  << "\n";
      std::cout << fnc(9,9) << "\n";
    }

    Какая крестопараша )))

    j123123, 23 Июля 2021

    Комментарии (95)
  9. C++ / Говнокод #27486

    +1

    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
    // https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/global/qglobal.h?h=v5.13.1#n1017
    
    #if __cplusplus >= 201703L
    // Use C++17 if statement with initializer. User's code ends up in a else so
    // scoping of different ifs is not broken
    #define Q_FOREACH(variable, container)                                   \
    for (auto _container_ = QtPrivate::qMakeForeachContainer(container);     \
         _container_.i != _container_.e;  ++_container_.i)                   \
        if (variable = *_container_.i; false) {} else
    #else
    // Explanation of the control word:
    //  - it's initialized to 1
    //  - that means both the inner and outer loops start
    //  - if there were no breaks, at the end of the inner loop, it's set to 0, which
    //    causes it to exit (the inner loop is run exactly once)
    //  - at the end of the outer loop, it's inverted, so it becomes 1 again, allowing
    //    the outer loop to continue executing
    //  - if there was a break inside the inner loop, it will exit with control still
    //    set to 1; in that case, the outer loop will invert it to 0 and will exit too
    #define Q_FOREACH(variable, container)                                \
    for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
         _container_.control && _container_.i != _container_.e;         \
         ++_container_.i, _container_.control ^= 1)                     \
        for (variable = *_container_.i; _container_.control; _container_.control = 0)
    #endif

    А можно ли свой foreach сделать через какую-нибудь шаблонопарашу? Или тут, как обычно, нужна гомоиконность?

    j123123, 28 Июня 2021

    Комментарии (74)
  10. C++ / Говнокод #27483

    +5

    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
    #include <unistd.h>
    #include <stdio.h>
    #include <limits.h>
    
    template<size_t Size> struct static_string {char data[Size];};
    template<size_t ... Indexes>struct index_sequence {};
    template<size_t Size, size_t ... Indexes>
    constexpr static_string<sizeof ... (Indexes) + 1> make_static_string(const static_string<Size>& str,index_sequence<Indexes ...>) {return {str.data[Indexes] ..., '\0'};}
    constexpr static_string<1> make_static_string() {return {'\0'};}
    template<size_t Size, size_t ... Indexes>
    struct make_index_sequence : make_index_sequence<Size - 1, Size - 1, Indexes ...> {};
    template<size_t Size>
    constexpr static_string<Size> make_static_string(const char (& str)[Size]) {return make_static_string(str, make_index_sequence<Size - 1>{});}
    template<size_t ... Indexes>
    struct make_index_sequence<0, Indexes ...> : index_sequence<Indexes ...> {};
    template<size_t Size, size_t ... Indexes>
    constexpr static_string<sizeof ... (Indexes) + 1> make_static_string(const char (& str)[Size],index_sequence<Indexes ...>) {return {str[Indexes] ..., '\0'};}
    template<size_t Size>
    constexpr size_t static_string_find(const static_string<Size>& str, char ch, size_t from, size_t nth) {return Size < 2 || from >= Size - 1 ? UINT_MAX :str.data[from] != ch ? static_string_find(str, ch, from + 1, nth) :nth > 0 ? static_string_find(str, ch, from + 1, nth - 1) : from;}
    template<size_t Size>
    constexpr size_t static_string_find_0(const static_string<Size>& str, char ch, size_t from, size_t nth) {return Size < 2 || from >= Size - 1 ? 0 : str.data[from] != ch ? static_string_find_0(str, ch, from + 1, nth) :nth > 0 ? static_string_find(str, ch, from + 1, nth - 1) : from;}
    template<size_t Size1, size_t ... Indexes1, size_t Size2, size_t ... Indexes2>
    constexpr static_string<Size1 + Size2 - 1> static_string_concat_2(const static_string<Size1>& str1, index_sequence<Indexes1 ...>,const static_string<Size2>& str2, index_sequence<Indexes2 ...>) {return {str1.data[Indexes1] ..., str2.data[Indexes2] ..., '\0'};}
    template<size_t Size1, size_t Size2>
    constexpr static_string<Size1 + Size2 - 1> static_string_concat_2(const static_string<Size1>& str1, const static_string<Size2>& str2) {return static_string_concat_2(str1, make_index_sequence<Size1 - 1>{},str2, make_index_sequence<Size2 - 1>{});}
    template<size_t Begin, size_t End, size_t ... Indexes>
    struct make_index_subsequence : make_index_subsequence<Begin, End - 1, End - 1, Indexes ...> {};
    template<size_t Pos, size_t ... Indexes>
    struct make_index_subsequence<Pos, Pos, Indexes ...> : index_sequence<Indexes ...> {};
    template<size_t Begin, size_t End, size_t Size>
    constexpr static_string<End - Begin + 1> static_string_substring(const static_string<Size>& str) {return make_static_string(str, make_index_subsequence<Begin, End>{});}
    template<size_t Begin, size_t Size>
    constexpr static_string<Size - Begin> static_string_suffix(const static_string<Size>& str) {return static_string_substring<Begin, Size - 1>(str);}
    #define remove_underscore(arg) ([] () __attribute__((always_inline)) {constexpr auto a = static_string_find(make_static_string(arg),'_',0,0) == UINT_MAX? make_static_string(arg):static_string_concat_2(static_string_concat_2(static_string_substring<0,static_string_find_0(make_static_string(arg),'_',0,0)>(make_static_string(arg)),static_string_suffix<static_string_find_0(make_static_string(arg),'_',0,0)+1>(make_static_string(arg))),make_static_string("\0"));return a;}().data)
    
    int main()
    {
        puts(remove_underscore("_testtest"));
        puts(remove_underscore("test_test"));
        puts(remove_underscore("testtest_"));
    }

    Убогий constexpr в c++11

    mittorn, 25 Июня 2021

    Комментарии (46)