Здравствуйте, LaptevVV, Вы писали:
LVV>Она очень полезна.
В C/C++ хотя бы зарезервированные слова есть. В Фортране и этого не было. Да ещё он пробелы игнорировал.
LVV>Для начинающих — откровение увидеть, как сложение 2 положительных становится отрицательным.
Нас этому на ТОЭ для программистов учили, помню. Ещё, кстати, начинающих повергает в шок, что целые числа не являются подмножеством вещественных, а это существенно различные объекты, когда речь идёт о машинных вычислениях.
LVV>Неявные преобразования — зло абсолютное.
Повбывав бы.
LVV>Теперь у меня для студентов есть аргументированный источник примеров. LVV>Не совсем уж тривиальных.
Да не только для студентов. Я вот ни разу не плюсовик, но иногда, довольно редко, пригодится и сейчас его брать. Всякие мелкие плагины делать. Шанс нарваться на грабли весьма высок.
Здравствуйте, alpha21264, Вы писали:
M>> Но, конечно, если у тебя при компиляции "кучи ненужных варнингов" (c) (tm), но будут грабли.
A>Все твои проблемы от того, что ты не понимаешь слова. A>В данном случае ты не понимаешь, что варнинги бывают "нужные" и "ненужные".
Не бывает ненужных варнингов. Все варнинги нужные. Каждый варнинг надо разбирать, смотреть, почему он был выдан.
С некоторыми я не разбирался особо, вроде работает, но надо бы будет разобраться. Для MSVC у меня такой список:
target_compile_options(${TARGET} PRIVATE "/WX" "/external:anglebrackets" "/external:W1")
# !!! Надо разобратся со всеми этими варнингами. Пока дизаблим
# warning C4435: 'TYPE': Object layout under /vd2 will change due to virtual base 'TYPE_BASE'
target_compile_options(${TARGET} PRIVATE "/wd4435")
# warning C4464: exclude warning "relative include path contains '..'"
target_compile_options(${TARGET} PRIVATE "/wd4464")
# warning C4505: unreferenced function has been removed
target_compile_options(${TARGET} PRIVATE "/wd4514")
# warning C4626: 'TYPE': assignment operator was implicitly defined as deleted
target_compile_options(${TARGET} PRIVATE "/wd4626")
# https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4710?view=msvc-170
# warning C4710: function not inlined
target_compile_options(${TARGET} PRIVATE "/wd4710")
# warning C4711: function selected for automatic inline expansion
target_compile_options(${TARGET} PRIVATE "/wd4711")
# warning C4738: storing 32-bit float result in memory, possible loss of performance
target_compile_options(${TARGET} PRIVATE "/wd4738")
# warning C4810: value of pragma pack(show)
# target_compile_options(${TARGET} PRIVATE "/wd4810")
# warning C4820: N bytes padding added after data member 'memberName'
target_compile_options(${TARGET} PRIVATE "/wd4820")
# warning C4866: compiler may not enforce left-to-right evaluation order for call to 'umba::SimpleFormatter::operator<<<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >'
target_compile_options(${TARGET} PRIVATE "/wd4866")
# warning C5027: 'TYPE': move assignment operator was implicitly defined as deleted
target_compile_options(${TARGET} PRIVATE "/wd5027")
# warning C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
target_compile_options(${TARGET} PRIVATE "/wd5045")
Ещё у меня есть специальные инклюды (но они используются очень редко), которыми я оборачиваю проблемное место после разбирательства (лежат в моей "главной" базовой либе в подкаталоге warnings):
Здравствуйте, LaptevVV, Вы писали:
LVV>Рекомендую!
Валерий Викторович, я очень давно не программировал но в свое время неплохо разбирался в C++98. Я не думаю что в механизме виртуальных функций что-нибудь изменилось с тех пор. Поэтому сообщаю вам что вот в этом разделе написана абсолютная чушь:
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Валерий Викторович, я очень давно не программировал но в свое время неплохо разбирался в C++98. Я не думаю что в механизме виртуальных функций что-нибудь изменилось с тех пор. Поэтому сообщаю вам что вот в этом разделе написана абсолютная чушь:
ЛБ>https://github.com/Nekrolm/ubbook/blob/master/runtime/virtual_functions.md
ЛБ>Человек пишет о том в чем не разобрался и судя по всему даже не заглядывал в текст стандарта.
Здравствуйте, so5team, Вы писали:
S>И что конкретно там не так?
Все. Там написано:
В конструкторах и деструкторах в C++ виртуальная диспетчеризация методов не работает
Это чушь. Работает.
Единственная проблема в приведенном коде — вызов чисто виртуальной функции в ctor/dtor. Убери в этом коде =0 при описании виртуальных функций и их можно вызывать в ctor/dtor.
ЛБ>Единственная проблема в приведенном коде — вызов чисто виртуальной функции в ctor/dtor. Убери в этом коде =0 при описании виртуальных функций и их можно вызывать в ctor/dtor.
указатель на виртуальную ф-ию прописывается при вызове конструктора. вызывая виртуальную ф-ию из конструктора или деструктора человек непонятно чего собирается добиться.
Здравствуйте, so5team, Вы писали:
S>Правда что ли? А это тогда как объяснить:
Читайте стандарт. В стандарте 98 года было так:
12.7 (3)
... When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data-member) or from a destructor, and the object to which a call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor's own class or in one of its bases, ...
S>ЗЫ. Для компиляции в режиме C++11 или более свежих стандартов для f нужно поставить override. Я просто в режиме C++98 проверял.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Здравствуйте, so5team, Вы писали:
S>>Правда что ли? А это тогда как объяснить:
ЛБ>Читайте стандарт. В стандарте 98 года было так:
ЛБ>
12.7 (3)
ЛБ>... When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data-member) or from a destructor, and the object to which a call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor's own class or in one of its bases, ...
Тогда какие претензии к главе статьи? Там именно об этом речь и идет. И мой пример именно это и демонстрирует.
В конструкторах и деструкторах в C++ виртуальная диспетчеризация методов не работает
ЛБ>Это чушь. Работает.
ЛБ>Единственная проблема в приведенном коде — вызов чисто виртуальной функции в ctor/dtor. Убери в этом коде =0 при описании виртуальных функций и их можно вызывать в ctor/dtor.
Вызвать-то можно, весь вопрос только в том, что из этого получится. Некоторые ошибочно ожидают, что будет вызвана версия виртуальной функции из наследника, а вызвается либо собственная, либо вообще версия из базового класса, если собственной не предоставлено. Этим же объясняется, почему вообще возможeн pure virtual call.
#include <iostream>
#include <memory>
class Base
{
public:
virtual void Stop() { std::cout << "Base::Stop" << std::endl; }
virtual ~Base() {
Stop(); // Вот здесь будет вызван Base::Stop, а не Derived::Stop, как некоторые ожидают.
}
};
class Derived : public Base
{
public:
virtual void Stop() { std::cout << "Derived::Stop" << std::endl; }
};
int main() {
std::shared_ptr<Derived> derived_ptr = std::make_shared<Derived>();
// При выходе: "Base::stop"
}
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, so5team, Вы писали:
S>Тогда какие претензии к главе статьи? Там именно об этом речь и идет. И мой пример именно это и демонстрирует.
Там про UB. Там написано не работает. А на самом деле работает и никакого UB от этого нет. UB там по другой причине — вызов pure virtual function в ctor/dtor. И как раз об этом автор ничего не говорит.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Там написано не работает. А на самом деле работает
И как же оно работает, если при вызове виртуального метода, у которого есть новая версия в производном классе, вызывается все-таки версия из базового класса?
Ведь виртуальность в том и состоит, что мы дергаем метод через указатель/ссылку на базовый класс, а получаем вызов кода из производного класса. Но в конструкторах/деструкторах именно этого-то эффекта и нет.
Именно об этом автор книги и пишет русским по белому:
В конструкторах и деструкторах в C++ виртуальная диспетчеризация методов не работает
Здравствуйте, so5team, Вы писали:
S>И как же оно работает, если при вызове виртуального метода, у которого есть новая версия в производном классе, вызывается все-таки версия из базового класса?
Вот до определенного уровня — до класса now under construction и работает. Если у тебя там 10 базовых классов и ты сделал override только во втором то этот override и будет вызван.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Вот до определенного уровня — до класса now under construction и работает.
Боюсь показаться грубым, но слово "работает" в данном случае не подходит. Тут как со второй свежестью.
Виртуальная диспетчеризация либо работает, либо нет.
И пишут что здесь проблема в том что "в конструкторах и деструкторах в C++ виртуальная диспетчеризация методов не работает". Я повторяю она работает и в стандарте написано как работает. Здесь всего одна проблема — виртуальный вызов чисто виртуальной функции. Вот это UB. И как раз об этом там ни слова.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Вот до определенного уровня — до класса now under construction и работает. Если у тебя там 10 базовых классов и ты сделал override только во втором то этот override и будет вызван.
Тут вот какая штука. В данном примере, вызов виртуальный фунции stop() в деструкторе ЗАВЕДОМО будет эквивалентен невиртуальной форме вызова: Processor::stop. Как при этом можно говорить о работоспособности виртуальной диспетчеризации? Устройство виртуальных механизмов стандарт языка ведь никак не регламентирует и в разных имплементациях языка он может быть разным.
--
Справедливость выше закона. А человечность выше справедливости.
ЛБ>Валерий Викторович, я очень давно не программировал но в свое время неплохо разбирался в C++98. Я не думаю что в механизме виртуальных функций что-нибудь изменилось с тех пор. Поэтому сообщаю вам что вот в этом разделе написана абсолютная чушь: ЛБ>https://github.com/Nekrolm/ubbook/blob/master/runtime/virtual_functions.md ЛБ>Человек пишет о том в чем не разобрался и судя по всему даже не заглядывал в текст стандарта.
Ну, выше уже знатоки расписали... ЛБ>А вы мне советуете выбросить на ветер 1140 рублей. Нехорошо.
Ну, ничего такого я не советовал.
Я рекомендовал книжку почитать.
Вот вы почитали, и пост родился. Другие заинтересуются...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>И пишут что здесь проблема в том что "в конструкторах и деструкторах в C++ виртуальная диспетчеризация методов не работает". Я повторяю она работает и в стандарте написано как работает. Здесь всего одна проблема — виртуальный вызов чисто виртуальной функции. Вот это UB. И как раз об этом там ни слова.
Какие у тебя есть основания утверждать, что виртуальная диспетчеризация работает, когда вызов stop() ЗАВЕДОМО эквивалентен невиртуальному вызову Processor::stop()?
"Можно вызвать" не то же самое, что "работает виртуальная диспетчеризация".
--
Справедливость выше закона. А человечность выше справедливости.