Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326

Открыть новую тему     Написать ответ в эту тему

Crazy_Shrike



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Вопросы по программированию на C/С++

 
  • Справочники, книги
  • Выбор IDE (среды программирования)
     
    Постарайтесь дать как можно больше информации о возникшей проблеме - это в конце концов в ваших же интересах чтобы вам помогли.

    Решения конкретных задач собираются и обсуждаются в теме Задачи по C/С++ .

    Прежде чем просить помощи в задании...
    Если позарез надо и вы даже готовы заплатить

    Как правильно задавать вопросы, если вы хотите получить ответ.

    Полезные ссылки:
    C++(eng)

  • Всего записей: 241 | Зарегистр. 25-03-2004 | Отправлено: 13:37 06-05-2004 | Исправлено: AZJIO, 19:45 12-05-2014
    BabaDeda

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    неконстантный ссылочный тип TestClass& в параметрах требует lvalue, а TestClass() это rvalue

    Всего записей: 4 | Зарегистр. 06-03-2007 | Отправлено: 21:19 19-04-2025
    zzz528

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    V0lt
    я проверил на 2017 студии (ewdk) - ошибки нет, может в более новых так уже нельзя.
     
    Добавлено:
    и на 2019 нет ошибки

    Всего записей: 2227 | Зарегистр. 20-06-2005 | Отправлено: 21:25 19-04-2025
    V0lt



    Platinum Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    BabaDeda

    Цитата:
    неконстантный ссылочный тип TestClass& в параметрах требует lvalue, а TestClass() это rvalue

    Спасибо, вот сейчас дошло.
    Но выглядит как баг, потому что если TestClass() вытащить наружу, то заработает.

    Код:
    auto test3 = TestClass();
    test1.swap(test3); // OK

     
    zzz528

    Цитата:
    я проверил на 2017 студии (ewdk) - ошибки нет, может в более новых так уже нельзя.

    Какие-то доп. параметры могут влиять.
    Я сейчас ковыряю проект, который без ошибки собирается в C++17 и кидает ошибку, если переключить на C++20. А указанный простой пример у меня кидает ошибку всегда.

    Всего записей: 11254 | Зарегистр. 05-02-2003 | Отправлено: 21:52 19-04-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    V0lt

    Цитата:
    Но выглядит как баг, потому что если TestClass() вытащить наружу, то заработает.  

    Люди решили, что временная переменная, которая будет уничтожена после выполнения выражения (достижения следующего sequence point), не должна меняться. С одной стороны, дурь несусветная -- даже придумали синтаксис TestClass&& для тех, "кому действительно надо". В качестве примера, когда оно надо, можно рассмотреть сценарий некоторого временного connection, который создается под конкретную локальную задачу и тут же закрывается и удаляется. Так, вместо
    doSomething (makeConnection(...));
    Приходилось извращаться со скобками:
    {
       Connection con = makeConnection(...);
       doSomething(con);
    }
    К сожалению, именно Ваш случай демонстрирует то, ради чего это все затевалось: у Вас  
    test1.swap(TestClass()); // C2664
    перенесет данные (возможно, большое их количество) во временную переменную, которая при достижении ; будет тут же удалена. Электроэнергия и процессорное время будут потрачены зря, на что сторонники "правильного" программирования будут пенять. Чтобы избежать такого неэффективного использования языка, данную возможность решили запретить. При этом запретили и вполне себе эффективные и правомерные другие сценарии, но, лес рубят -- щепки летят.

    Цитата:
    Какие-то доп. параметры могут влиять.

    Да, ключ /Za. В предыдущих версиях майкрософтовского компилятора для совместимости "все работало", и чтоб писать "правильно", надо было использовать этот ключ.

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 06:11 20-04-2025
    MBK2

    Gold Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    перенесет данные (возможно, большое их количество)  

    Указатель?

    Цитата:
    Электроэнергия и процессорное время будут потрачены зря


    Всего записей: 5478 | Зарегистр. 18-09-2018 | Отправлено: 07:45 20-04-2025
    V0lt



    Platinum Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Да, ключ /Za. В предыдущих версиях майкрософтовского компилятора для совместимости "все работало", и чтоб писать "правильно", надо было использовать этот ключ.

    Я его включал-выключал - ничего не меняется. Ну и фиг с ним.
     
    Еще меня ошибка C2362 озадачила.

    Цитата:
    int main() {
       goto label1;
       int i = 1;      // C2362, initialization skipped
    label1:;
    }

    Что в этом примере может в принципе сломаться?
     
    Аналогично есть проект, который без ошибки собирается в C++17 и кидает ошибку, если переключить на C++20.

    Всего записей: 11254 | Зарегистр. 05-02-2003 | Отправлено: 08:26 20-04-2025
    MBK2

    Gold Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    V0lt

    Цитата:
    Что в этом примере может в принципе сломаться?

    Как что? Обход инициализации переменной.

    Всего записей: 5478 | Зарегистр. 18-09-2018 | Отправлено: 09:00 20-04-2025
    V0lt



    Platinum Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    MBK2

    Цитата:
    Обход инициализации переменной

    Которая до goto и после label1 никак не используется.
     
    Официальное решение заключить инициализацию в фигурные скобки. Обход инициализации все так же присутствует. ИМХО бред. Как будто компилятор не сможет рассчитать реальную область видимости переменной. Что в принципе он и делает, если не мешают ключи компиляции.
     
    Добавлено:
    Можно и без фигурных скобок между goto и label1 инициализировать i.

    Код:
    void set(int& v) {
        v = 1;
    }
     
    int main() {
        goto label1;
        int i;
        set(i);
    label1:;
    }

    У будет все хорошо.
     
    Я понимаю, что формально фигурные скобки тут как бы есть и объявление переменной не является инициализацией. Но блин проблему с названием "initialization skipped" неправильно решать оборачиванием в фигурные скобки. Инициализация переменной в любом случае будет пропущена.
    Хотя может у меня претензия только к MSVC, а в других компиляторах по нормальному написано.

    Всего записей: 11254 | Зарегистр. 05-02-2003 | Отправлено: 09:11 20-04-2025 | Исправлено: V0lt, 09:37 20-04-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    V0lt

    Цитата:
    Что в этом примере может в принципе сломаться?

    Stack frame. Место под переменную i выделяется на стеке путем прибавления к регистру SP (stack pointer в интеловской архитектуре) значения 4 (или сколько там int занимает). При выходе из функции произойдет вычитание этого четыре. Если Вы перепрыгните SP = SP + 4, но выполните SP = SP - 4, то вы сломаете стек программы и она, скорее всего, упадет.
    Обратите внимание, что я ответил в точности на тот вопрос, что был задан, как на собеседовании (а это хороший вопрос именно для него). И ключевое слово было "в принципе", поскольку в реальной жизни умный компилятор это увидит и либо стек подкрутит, либо ошибку/предупреждение выдаст.

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 22:22 20-04-2025
    MBK2

    Gold Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Rock

    Цитата:
    Место под переменную i выделяется на стеке путем прибавления к регистру SP (stack pointer в интеловской архитектуре) значения 4 (или сколько там int занимает). При выходе из функции произойдет вычитание этого четыре. Если Вы перепрыгните SP = SP + 4, но выполните SP = SP - 4, то вы сломаете стек программы и она, скорее всего, упадет

    Сильно сомнительно. Обычно место под локальные переменные выделяется при входе в функцию, а освобождается по выходу из нее.

    Всего записей: 5478 | Зарегистр. 18-09-2018 | Отправлено: 19:32 21-04-2025 | Исправлено: MBK2, 19:32 21-04-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    MBK2

    Цитата:
    Сильно сомнительно. Обычно место под локальные переменные выделяется при входе в функцию, а освобождается по выходу из нее.

    Ну, я, в отличие от всех вас тут, и проверить могу (хоть мне это и не надо):
     
    #include <iostream>
     
    int main() {
        {
            int i1 = 0;
            std::cout << &i1 << std::endl;
        }
        {
            int i2 = 0;
            std::cout << &i2 << std::endl;
        }
    }

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 22:39 21-04-2025
    MBK2

    Gold Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Rock

    Цитата:
    я, в отличие от всех вас тут

    Отучаемся считать себя исключительным, проверить элементарно
    Ваш код компилируется в такое:

    Код:
     
    .text:004118A0 ; int __cdecl main_0(int argc, const char **argv, const char **envp)
    .text:004118A0 _main_0         proc near               ; CODE XREF: _main&#8593;j
    .text:004118A0
    .text:004118A0 var_DC          = byte ptr -0DCh
    .text:004118A0 var_18          = dword ptr -18h
    .text:004118A0 var_C           = dword ptr -0Ch
    .text:004118A0 var_4           = dword ptr -4
    .text:004118A0 argc            = dword ptr  8
    .text:004118A0 argv            = dword ptr  0Ch
    .text:004118A0 envp            = dword ptr  10h
    .text:004118A0
    .text:004118A0                 push    ebp
    .text:004118A1                 mov     ebp, esp
    .text:004118A3                 sub     esp, 0DCh
    .text:004118A9                 push    ebx
    .text:004118AA                 push    esi
    .text:004118AB                 push    edi
    .text:004118AC                 lea     edi, [ebp+var_DC]
    .text:004118B2                 mov     ecx, 37h
    .text:004118B7                 mov     eax, 0CCCCCCCCh
    .text:004118BC                 rep stosd
    .text:004118BE                 mov     eax, ___security_cookie
    .text:004118C3                 xor     eax, ebp
    .text:004118C5                 mov     [ebp+var_4], eax
    .text:004118C8                 mov     ecx, offset unk_41C027
    .text:004118CD                 call    j_@__CheckForDebuggerJustMyCode@4 ; __CheckForDebuggerJustMyCode(x)
    .text:004118D2                 mov     [ebp+var_C], 0
    .text:004118D9                 mov     esi, esp
    .text:004118DB                 push    offset sub_41124E
    .text:004118E0                 mov     edi, esp
    .text:004118E2                 lea     eax, [ebp+var_C]
    .text:004118E5                 push    eax
    .text:004118E6                 mov     ecx, dscout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::ostream std::cout
    .text:004118EC                 call    ds?6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@PBX@Z ; std::ostream::operator<<(void const *)
    .text:004118F2                 cmp     edi, esp
    .text:004118F4                 call    j___RTC_CheckEsp
    .text:004118F9                 mov     ecx, eax
    .text:004118FB                 call    ds?6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::ostream::operator<<(std::ostream & (*)(std::ostream &))
    .text:00411901                 cmp     esi, esp
    .text:00411903                 call    j___RTC_CheckEsp
    .text:00411908                 mov     [ebp+var_18], 0
    .text:0041190F                 mov     esi, esp
    .text:00411911                 push    offset sub_41124E
    .text:00411916                 mov     edi, esp
    .text:00411918                 lea     eax, [ebp+var_18]
    .text:0041191B                 push    eax
    .text:0041191C                 mov     ecx, dscout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::ostream std::cout
    .text:00411922                 call    ds?6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@PBX@Z ; std::ostream::operator<<(void const *)
    .text:00411928                 cmp     edi, esp
    .text:0041192A                 call    j___RTC_CheckEsp
    .text:0041192F                 mov     ecx, eax
    .text:00411931                 call    ds?6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::ostream::operator<<(std::ostream & (*)(std::ostream &))
    .text:00411937                 cmp     esi, esp
    .text:00411939                 call    j___RTC_CheckEsp
    .text:0041193E                 xor     eax, eax
    .text:00411940                 push    edx
    .text:00411941                 mov     ecx, ebp        ; Esp
    .text:00411943                 push    eax
    .text:00411944                 lea     edx, Fd         ; Fd
    .text:0041194A                 call    j_@_RTC_CheckStackVars@8 ; _RTC_CheckStackVars(x,x)
    .text:0041194F                 pop     eax
    .text:00411950                 pop     edx
    .text:00411951                 pop     edi
    .text:00411952                 pop     esi
    .text:00411953                 pop     ebx
    .text:00411954                 mov     ecx, [ebp+var_4]
    .text:00411957                 xor     ecx, ebp        ; StackCookie
    .text:00411959                 call    j_@__security_check_cookie@4 ; __security_check_cookie(x)
    .text:0041195E                 add     esp, 0DCh
    .text:00411964                 cmp     ebp, esp
    .text:00411966                 call    j___RTC_CheckEsp
    .text:0041196B                 mov     esp, ebp
    .text:0041196D                 pop     ebp
    .text:0041196E                 retn
    .text:0041196E _main_0         endp
     

     
    Сами видите или поянения нужны?

    Всего записей: 5478 | Зарегистр. 18-09-2018 | Отправлено: 08:42 22-04-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    MBK2

    Цитата:
    Ваш код компилируется в такое

    Попробуйте другие ключи компиляции. В С++, в отличие от С, разрешили переменные внутри вложенных областей видимости именно для этого. Если оно не работает, значит, что-то сделано не так. Почему оно не работает, тоже совершенно понятно, и это тоже хороший вопрос на собеседовании, хотя вопрос про переменные области видимости намного сложнее и интереснее, заодно и объясняет вообще все. Похоже, Вы не просекли идею.

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 16:16 22-04-2025
    MBK2

    Gold Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Rock
    Да нет, я идею просек, я к тому, что если не играться с японской бензопилой, то она по умолчанию работает нормально.

    Всего записей: 5478 | Зарегистр. 18-09-2018 | Отправлено: 17:42 22-04-2025
    V0lt



    Platinum Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Хочу в родительском классе объявить std::span из C++20, а инициализировать его лишь в классах потомках. Такое возможно?
     
    Накидал пример:

    Код:
    #include <span>
     
    int array1[] = { 1,2,3,4,5 };
    int array2[] = { 7,8,9 };
     
    class A
    {
    public:
        std::span<int> kit;
    };
     
    class B : public A
    {
    public:
        B() : kit(array1) {}
    };
     
    class C : public A
    {
    public:
        C() : kit(array2) {}
    };

    Всего записей: 11254 | Зарегистр. 05-02-2003 | Отправлено: 19:59 16-05-2025 | Исправлено: V0lt, 20:00 16-05-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    V0lt

    Цитата:
    а инициализировать его лишь в классах потомках. Такое возможно?


    Цитата:
    class B : public A
    {
    public:
        B() : kit(array1) {} // AAAA
    };

     
    Нет. Инициализировать члены-данные А можно только в конструкторе А и параметры для инициализации придется пробрасывать туда. Так, в АААА А::kit уже проинициализирован после отработки конструктора А -- он, по очевидным причинам, отработает до начала работы конструктора В. В конструкторе В Вы можете только присвоить kit новое значение.

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 22:20 16-05-2025
    KChernov



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Rock
    А почему нельзя kit сделать protected, а A - virtual?

    Всего записей: 2779 | Зарегистр. 20-04-2004 | Отправлено: 22:31 16-05-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    KChernov

    Цитата:
    А почему нельзя kit сделать protected, а A - virtual?

    Данный вопрос некорректный -- это сделать можно. Только означать оно будет, скорее всего, не то, что Вы себе представляете.

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 22:35 16-05-2025
    V0lt



    Platinum Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Rock

    Цитата:
    В конструкторе В Вы можете только присвоить kit новое значение.

    Как присвоить kit новое значение в конструкторе B?

    Всего записей: 11254 | Зарегистр. 05-02-2003 | Отправлено: 22:47 16-05-2025
    Rock

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    V0lt

    Цитата:
    Как присвоить kit новое значение в конструкторе B?

    Новое значение переменной kit в конструкторе В можно присвоить с помощью оператора присваивания.

    Всего записей: 1293 | Зарегистр. 10-04-2003 | Отправлено: 22:54 16-05-2025
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2025

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru