С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/C++: IDE, инструментарий
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
1 / 1 / 0
Регистрация: 08.08.2021
Сообщений: 18

Компилятор игнорирует создание экземпляра класса из-за оптимизации

23.10.2021, 15:37. Показов 5370. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Премного благодарю вас, что решили вникнуть в суть вопроса, а, возможно, даже помочь.
Работаю в Visual Studio 2019 - проект стабильно работает без ошибок в Debug x64/x86 версиях, но мне требуется перевести программу в стабильную Release версию, в которой компилятор игнорирует важный участок кода, который отвечает за создание экземпляров различных классов, наследуемых от одного абстрактного класса.
Этого можно избежать, если полностью отключить оптимизацию, что не желательно.
Как можно предотвратить ошибку в данной ситуации?

Я считаю, что в этом нет особого смысла, но на всякий случай предоставлю данный участок кода из main функции, который игнорируется.
Здесь я присваиваю константной ссылке основного производного класса его различных потомков, которые используются в будущем при помощи общего интерфейса.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
const Factory::Abstract &f1 = Factory::Family(Function::FNV1a::Creator(), Algorithm::DoubleHashing::Creator(0, 1));
const Factory::Abstract &f2 = Factory::Family(Function::FNV1a::Creator(), Algorithm::PseudorandomProbing::Creator(0));
const Factory::Abstract &f3 = Factory::One(Function::Standart::Creator(), Algorithm::LinearProbing::Creator());
const Factory::Abstract &f4 = Factory::One(Function::Standart::Creator(), Algorithm::QuadraticProbing::Creator());
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.10.2021, 15:37
Ответы с готовыми решениями:

Создание экземпляра класса - наследника экземпляра другого класса
Имеется два класса: класс Layer и класс-наследник Neuron. Я создал экземпляр класса Layer l1 и задал его свойства, теперь мне необходимо...

Создание нового экземпляра дочернего класса из экземпляра базового
Всем привет! Извиняюсь, если вопрос глупый, но что-то не смог найти конкретный ответ на него... У меня есть несколько классов: все они...

Создание экземпляра класса, разрушение экземпляра класса
Не могу найти информацию про разрущение экземпляра класса. Объясните пожалуйста, что это?

14
147 / 135 / 50
Регистрация: 14.05.2021
Сообщений: 642
23.10.2021, 15:57
С чего ты взял, что это компилятор что-то делает, а не просто ошибка в твоем коде?
0
1 / 1 / 0
Регистрация: 08.08.2021
Сообщений: 18
24.10.2021, 21:01  [ТС]
psergee, хочу обратить ваше внимание на цитирование моих слов.
Цитата Сообщение от Sidr Посмотреть сообщение
проект стабильно работает без ошибок в Debug x64/x86 версиях
Так же дополню тем, что говорил ранее - проект так же работает стабильно и без ошибок, если отключить оптимизацию.
0
147 / 135 / 50
Регистрация: 14.05.2021
Сообщений: 642
26.10.2021, 15:28
Цитата Сообщение от Sidr Посмотреть сообщение
psergee, хочу обратить ваше внимание на цитирование моих слов.
Эти слова ни о чем не говорят от слова совсем. Дебажная и релизная версии могут отличаться очень сильно. Проверь свой код на ошибки и UB. Это обычная ситуация при разработке, когда допущена ошибка, и в засивимости от опций компиляции код может по-разному работать, или вообще не работать.
В конце концов, у тебя есть полный код и дебаггер. Проверь в нем, что там у тебя происходит, и что там "игнорируется".
0
1 / 1 / 0
Регистрация: 08.08.2021
Сообщений: 18
26.10.2021, 22:41  [ТС]
С момента публикации данной темы я могу описать подробнее проблему:
Я воспользовался вашим советом - хочешь решить проблему, то решай её сам.
Ранее можно видеть, что мной использовались для хранения полиморфных объектов абстрактных классов константные ссылки, при инициализации которых r-values значением гарантированно продлевают срок хранения последних в соответствии со временем своей жизни (нахождения в области видимости), в данном случае до окончания работы программы - вся функция main, что исключало стирание данных.
Данный факт решено было проверить (сборка release x64 с оптимизацией), скриншот прилагаю:
Кликните здесь для просмотра всего текста

Мной было замечено нечто интересное. Переменная инициализировалась так как и должна, но компилятор показывает, что отсутствует указатель __vfptr из таблицы виртуальных методов. Спрашивается почему? Отнюдь не знаю...
Ведь, как я, повторяюсь, говорил ранее, что при отключении оптимизации, как при помощи директивы, описанной ниже, так и при помощи настроек компилятора, всё работает стабильно:
Кликните здесь для просмотра всего текста

Кликните здесь для просмотра всего текста
C++
1
2
3
#pragma optimize("", off)
/* Problems */
#pragma optimize("", on)

Без оптимизации всё работает - указатель указывает на конкретный адрес.
Однако мной было замечено, что при явном выделении памяти из кучи (я использовал smart poiner), всё будет работать так же стабильно, с чем это связано? Отнюдь не знаю...

Буду очень признателен, если Вы потратите немного своего драгоценного времени, psergee, чтобы вы могли удостовериться в этом сами!
Кликните здесь для просмотра всего текста

Хоть такая проблема всего и одна, но именно с такой подобной описанной выше встречаюсь впервые.

Получается, что я сам нашёл решение своей проблемы, как бы иронично это не звучало.
Надеюсь, я смог кому-то помочь в похожей ситуации и так же смог переубедить psergee, что код, написанный мной, не содержит никаких ошибок с моей стороны, как runtime, так и каких либо других.

Если кто-то знает ответ на вопрос: "Почему не инициализируется указатель на виртуальный метод из таблицы виртуальных методов в режиме оптимизации?", то буду крайне признателен за Ваш ответ!
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
26.10.2021, 23:54
Цитата Сообщение от Sidr Посмотреть сообщение
что код, написанный мной, не содержит никаких ошибок с моей стороны
Еще как содержит. Помимо того, что у большинства классов с виртуальными методами деструкторы не виртуальные, есть критические ошибки, связанные с хранением ссылок на объекты с automatic storage duration.
Первая строчка в main(это касается и последующих):
C++
1
factory_ptr fac1 { new Factory::Family(Function::FNV1a::Creator(),   Algorithm::DoubleHashing::Creator(0, 1))    };
Скажите, какое время жизни объектов, которые вы передаёте параметрами в конструктор Factory::Family?
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
27.10.2021, 08:57
Цитата Сообщение от zayats80888 Посмотреть сообщение
Помимо того, что у большинства классов с виртуальными методами деструкторы не виртуальные
В данном случае это не критично, потому что автор использует shared_ptr. Его конструктор сохраняет правильный deleter в соответствии с переданным типом.

Цитата Сообщение от zayats80888 Посмотреть сообщение
ошибки, связанные с хранением ссылок на объекты с automatic storage duration.
А вот это действительно проблема.
Работа с дохлыми объектами как раз и может приводить к описанным автором спецэффектам.

Добавлено через 4 минуты
Sidr, Это, кстати, достаточно распространенная ошибка полагать, что время жизни продлевается и в таких случаях.
Ну и еще более распространенная ошибка обвинять в таких случаях компилятор.
Сколько бы опыта у вас ни было, всегда нужно подвергать критике свои действия и знания.
1
1 / 1 / 0
Регистрация: 08.08.2021
Сообщений: 18
27.10.2021, 09:57  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Скажите, какое время жизни объектов, которые вы передаёте параметрами в конструктор Factory::Family?
Объекты, передаваемые параметрами в конструктор создаются в куче.

Цитата Сообщение от zayats80888 Посмотреть сообщение
критические ошибки, связанные с хранением ссылок на объекты с automatic storage duration.
Но разве не генерируется временная переменная?
Или дело не в продолжительности хранения?

Цитата Сообщение от DrOffset Посмотреть сообщение
Его конструктор сохраняет правильный deleter в соответствии с переданным типом.
Я не использую деструкторы совсем. Переменные-члены классов создаются при помощи smart-poiters или имеют автоматическое существование. На сколько я знаю, виртуальные деструкторы нужны для определения правильного поведения во время уничтожения объекта, но для меня это не играет роли, верно? Я могу ошибаться.

Цитата Сообщение от DrOffset Посмотреть сообщение
Это, кстати, достаточно распространенная ошибка полагать, что время жизни продлевается и в таких случаях.
Но ведь время жизни действительно продлевается
Я проверял, на скриншотах видно, что адрес указывает на область памяти, выделенной для объекта.
Или я что-то не понимаю?

Особенно остро вопрос стоит для указателя на виртуальную функцию.
Тут я тоже не могу понять, почему это происходит
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
27.10.2021, 10:24
Лучший ответ Сообщение было отмечено Sidr как решение

Решение

Цитата Сообщение от Sidr Посмотреть сообщение
Но ведь время жизни действительно продлевается
Но не в этом случае.
https://eel.is/c++draft/class.temporary#6
The exceptions to this lifetime rule are:

(6.9) A temporary object bound to a reference parameter in a function call ([expr.call]) persists until the completion of the full-expression containing the call.
В вашем коде функция с параметром-ссылкой - это конструктор (например)
C++
1
Family(const FFC_type &functionCreator, const FAC_type &algorithmCreator)
Т.е. безымянный объект Function::FNV1a::Creator() живет только до конца полного выражения.
Дальше же по ходу программы используется мертвая ссылка на него, сохраненная в объекте класса Family (в его Abstract-подобъекте).

Это классический случай UB, и поведение всей программы не определено, происходить может что угодно.

Добавлено через 5 минут
Цитата Сообщение от Sidr Посмотреть сообщение
Я проверял, на скриншотах видно, что адрес указывает на область памяти, выделенной для объекта.
Нужно понимать, что одно лишь наблюдение за UB (в том числе через отладчик) может менять наблюдаемое поведение. В физике это называется эффект наблюдателя.
Кроме того, само по себе наличие адреса никак не характеризует, жив у вас объект или нет.

Добавлено через 10 минут
Цитата Сообщение от Sidr Посмотреть сообщение
На сколько я знаю, виртуальные деструкторы нужны для определения правильного поведения во время уничтожения объекта, но для меня это не играет роли, верно?
Верно, для вас это не играет роли, но уничтожение объекта через базовый указатель без наличия виртуального деструктора также приводит к UB.
Однако, как я уже сказал, в вашем случае этой проблемы нет, т.к. shared_ptr сам заботится о назначении правильного deleter`а исходя из переданного в его конструктор типа. Это было бы проблемой, если бы вы использовали unique_ptr, но с shared_ptr - все нормально.
1
1 / 1 / 0
Регистрация: 08.08.2021
Сообщений: 18
27.10.2021, 15:30  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Но не в этом случае.
https://eel.is/c++draft/class.temporary#6
Благодарю вас! Я прочитал на столько вникая, на сколько позволяет мой уровень владения английским языком.
Хотел уточнить, относится ли данное исключение, выделенное в подраздел, конкретно к моей проблеме?
https://timsong-cpp.github.io/... orary#6.12
Если нет, то что именно? Конечно, если вам не затруднит ответить.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
27.10.2021, 15:49
Цитата Сообщение от Sidr Посмотреть сообщение
Хотел уточнить, относится ли данное исключение, выделенное в подраздел, конкретно к моей проблеме?
В данном случае нет, потому что у вас есть конструктор. Относится именно выделенное мной выше.
Если бы у вас не было конструктора у типа, то да, тогда бы и этот пункт стал относиться.
1
147 / 135 / 50
Регистрация: 14.05.2021
Сообщений: 642
27.10.2021, 16:00
Цитата Сообщение от Sidr Посмотреть сообщение
Буду очень признателен, если Вы потратите немного своего драгоценного времени, psergee, чтобы вы могли удостовериться в этом сами!
Удостоверились? Открываейте багу на компилятор, что я могу сказать. Проблема в нем. Как и у доброй четверти пользователей С++ - виноват компилятор

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от Sidr Посмотреть сообщение
Надеюсь, я смог кому-то помочь в похожей ситуации и так же смог переубедить psergee, что код, написанный мной, не содержит никаких ошибок с моей стороны
Ты не догадываешься, сколько тут таких каждый день уверенных в безошибочности своего кода и в ошибочности компилятора.

0
1 / 1 / 0
Регистрация: 08.08.2021
Сообщений: 18
27.10.2021, 16:55  [ТС]

Не по теме:

Не поймите меня неправильно.
Вы разбираетесь в своём деле и это достойно уважения и, надеюсь, будете сопутствовать единомышленникам в данной тяжёлой стезе не только догадками, но и помощью в их нахождении.
Отмечу, всё же проблема была не в ошибке кода, а в UB - разные вещи, согласитесь.
Кто знает, может человек не сдвинется с места уже как 3-ий / 5-ый день, а от советов решить проблемы самому пропадает мотивация идти дальше.
Надеюсь на понимание и желаю, чтобы люди желали Вам успехов и всего наилучшего, как и я.

0
147 / 135 / 50
Регистрация: 14.05.2021
Сообщений: 642
27.10.2021, 16:59
Цитата Сообщение от Sidr Посмотреть сообщение
Отмечу, всё же проблема была не в ошибке кода, а в UB - разные вещи, согласитесь.
Не соглашусь. Я уже писал:
Цитата Сообщение от psergee Посмотреть сообщение
Проверь свой код на ошибки и UB.
Цитата Сообщение от Sidr Посмотреть сообщение
Кто знает, может человек не сдвинется с места уже как 3-ий / 5-ый день, а от советов решить проблемы самому пропадает мотивация идти дальше.
А ты попробуй не на компилятор валить, а сразу все данные предоставлять, чтобы хотя бы можно было с чем-то работать.{deleted}

Добавлено через 1 минуту
Цитата Сообщение от Sidr Посмотреть сообщение
Надеюсь на понимание и желаю, чтобы люди желали Вам успехов и всего наилучшего, как и я.
Взаимно. Успехов во всем
0
28.10.2021, 00:29

Не по теме:

Цитата Сообщение от Sidr Посмотреть сообщение
всё же проблема была не в ошибке кода, а в UB - разные вещи, согласитесь.
Ну, все-таки, UB возникло из-за ошибки в коде.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.10.2021, 00:29
Помогаю со студенческими работами здесь

Создание экземпляра класса-наследника для переменной с типом базового класса
Подскажите чайнику как создается экземпляр класса BC BaseClass BC = new DerivedClass(); Вопрос: BC - это экземпляр класса BaseClass...

Явное создание экземпляра класса и явная специализация шаблона класса
Всем добрый день! Не могу разобраться - эти две технологии дают один и тот же результат? В каких случаях применять одно и другое?...

Создание экземпляра класса, имя класса находиться в строковой переменной
Подскажите люди добрые, как можно выйти из такой ситуации, вот допустим имеются классы class new1{ . . . } class new2{ . . ...

Пример класса с конструктором и деструктором, создание экземпляра класса через конструктор с параметрами
Привести пример класса с конструктором и деструктором, созданием экземпляра класса с помощью конструктора с параметрами.

Как можно изменить атрибут экземпляра одного класса при добавлении/изменении экземпляра другого класса
Мне нужно, чтобы при создании города/деревни уже существующей области (т.е. уже создана область с таким названием) изменялись атрибуты...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru