Re[3]: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: andrey.desman  
Дата: 07.03.24 15:53
Оценка:
Здравствуйте, Marty, Вы писали:

M>Почему он хочет копировать, а не перемещать?


У тебя же перемещение запрещено явно твоим NonCopiable.
Переместить он пытается, но тихо обламывается, потому что всегда можно скопировать если вдруг не прокатило. Далее пытается копировать, но и тут облом. Вот он и говорит, что скопировать не может.
Re: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: andrey.desman  
Дата: 07.03.24 15:56
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.


Суть другая. Во время return работает copy elision, copy/move конструкторы не нужны. Обламывается он в момент передачи в make_shared. Как только ты воткнул return std::move, то обламывается уже в момент return.

Разреши мув конструктор, все будет работать.
Re[3]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 16:38
Оценка: +3
Здравствуйте, Marty, Вы писали:

S>>Ну и как бы не видя базового класса это может превратиться в гадание по кофейной гуще.


M>
struct NonCopiableObject : public IObject
M>{
M>    NonCopiableObject() = default;

M>    NonCopiableObject(const NonCopiableObject&) = delete;
M>    NonCopiableObject& operator=(const NonCopiableObject&) = delete;

M>    NonCopiableObject(NonCopiableObject&&) = default;
M>    NonCopiableObject& operator=(NonCopiableObject&&) = default;

M>}; // struct NonCopiableObject

M>


Ну хорошо, а в IObject что? Ты в курсе, что, если ты объявил какой-то конструктор как default, это еще не гарантия того, что этот конструктор будет реально доступен? "default" на раз может реализоваться в "delete", если в классе присутствуют подобъекты(члены, базовые классы, члены базовых классов...) с явно или неявно удаленным конструктором.

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

Я бы предложил тебе поработать над минимизированным примером, воспроизводящем проблему, который можно было бы загрузить в какой-нибудь онлайн компилятор. И очень вероятно, что ошибку ты найдешь сам, в процессе работы над этим примером.
--
Отредактировано 07.03.2024 16:48 rg45 . Предыдущая версия . Еще …
Отредактировано 07.03.2024 16:40 rg45 . Предыдущая версия .
Re: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: rg45 СССР  
Дата: 07.03.24 16:43
Оценка:
Здравствуйте, Marty, Вы писали:

M>
M>        // return std::move(WindowTimerImpl(h, id, timeoutMs, true)); // !!! move version
M>


M>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.


Ну у тебя и так здесь rvalue выражение, что ты рассчитываешь получить еще от move?
--
Re[4]: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 17:03
Оценка:
Здравствуйте, andrey.desman, Вы писали:

M>>Почему он хочет копировать, а не перемещать?


AD>У тебя же перемещение запрещено явно твоим NonCopiable.

AD>Переместить он пытается, но тихо обламывается, потому что всегда можно скопировать если вдруг не прокатило. Далее пытается копировать, но и тут облом. Вот он и говорит, что скопировать не может.

Разве? Я думал, что = default говорит использовать ту версию, которую он сам сгенерил, не?
У меня в NonCopiable copy ctor/op= запрещены
Маньяк Робокряк колесит по городу
Re[2]: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 17:04
Оценка:
Здравствуйте, andrey.desman, Вы писали:

M>>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.


AD>Суть другая. Во время return работает copy elision, copy/move конструкторы не нужны. Обламывается он в момент передачи в make_shared. Как только ты воткнул return std::move, то обламывается уже в момент return.


AD>Разреши мув конструктор, все будет работать.


Да где ж он у меня запрещён-то?
Маньяк Робокряк колесит по городу
Re[4]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 17:07
Оценка:
Здравствуйте, rg45, Вы писали:


R>Ну хорошо, а в IObject что? Ты в курсе, что, если ты объявил какой-то конструктор как default, это еще не гарантия того, что этот конструктор будет реально доступен? "default" на раз может реализоваться в "delete", если в классе присутствуют подобъекты(члены, базовые классы, члены базовых классов...) с явно или неявно удаленным конструктором.


R>Смотри, как получается, ты ждешь, что тебе помогут, не показывая всего кода. Так можно потратить уйму времени с нулевым результатом.


Сорян
struct IObject
{
    virtual ~IObject() {}

}; // struct IObject



R>Я бы предложил тебе поработать над минимизированным примером, воспроизводящем проблему, который можно было бы загрузить в какой-нибудь онлайн компилятор. И очень вероятно, что ошибку ты найдешь сам, в процессе работы над этим примером.



Ну, пока решилось, были ошибочные представления о реализации make_shared в MSVC2019, из-за чего я пошел не тем путём

А, вспомнил, почему так получилось. Был код с make_shared, который в MSVC2019 не собирался, а у коллеги в MSVC2022 собирался. Мы поковыряли, и решили, что что-то не так с make_shared в MSVC2019
Маньяк Робокряк колесит по городу
Re[2]: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 17:11
Оценка: :)
Здравствуйте, rg45, Вы писали:

M>>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.


R>Ну у тебя и так здесь rvalue выражение, что ты рассчитываешь получить еще от move?


Я хотел сказать ему: "ну пожалуста-пожалуста, сделай мув"
Маньяк Робокряк колесит по городу
Re[4]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 17:18
Оценка:
Здравствуйте, andrey.desman, Вы писали:


AD>А,просмотрел, что мув разрешен. Тогда да, что-то не мувается по умолчанию.


Понять бы, что. По всей иерархии наследования никаких полей в классах нет, только чисто виртуальные функции. Ни конструкторов, ни операторов= никакиех нет вообще, только в финальном классе есть конструктор.
А в финальном классе так:

struct WindowTimerImpl : public IWindowTimer
{

    HWND         hWnd           = 0;
    UINT_PTR     idTimerEvent   = 0;
    timeout_t    timerTimeoutMs = 0;
    bool         running        = false;

    WindowTimerImpl(HWND h, UINT_PTR id, timeout_t timeoutMs, bool bRunning) : hWnd(h), idTimerEvent(id), timerTimeoutMs(timeoutMs), running(bRunning)
    {
        if (running)
        {
            restart();
        }
    }

};



До этого конструктор был приватным, и был публичный метод create.
Маньяк Робокряк колесит по городу
Re[5]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 17:25
Оценка:
Здравствуйте, Marty, Вы писали:


M>Ну, пока решилось, были ошибочные представления о реализации make_shared в MSVC2019, из-за чего я пошел не тем путём


M>А, вспомнил, почему так получилось. Был код с make_shared, который в MSVC2019 не собирался, а у коллеги в MSVC2022 собирался. Мы поковыряли, и решили, что что-то не так с make_shared в MSVC2019


Ну вообще, все, что приходит на вход std::make_shared форвардится в конструкторы объекта создаваемого класса. Конструкторы могут быть разные — копирования, перемещения, преобразования, с одним параметром и с несколькими. Если что-то работает не так, как ожидается, то я стараюсь все такие моменты доводить до полной ясности. Вот когда есть небольшой понятный примерчик, который и там и сям работает, а не работает только на каком-то определенном компиляторе или режиме, вот тогда тогда только можно говорить, что это баг компилятора. А так это просто предположение, а точная причина так и не выяснена пока.
--
Re[4]: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
От: T4r4sB Россия  
Дата: 07.03.24 17:28
Оценка: +1
Здравствуйте, Teolog, Вы писали:

M>>Почему он хочет копировать, а не перемещать?

T>А почему он должен хотеть перемещать?

Потому что результат вызова функции это rvalue?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[6]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 17:53
Оценка:
Здравствуйте, rg45, Вы писали:

R>Вот когда есть небольшой понятный примерчик, который и там и сям работает, а не работает только на каком-то определенном компиляторе или режиме, вот тогда тогда только можно говорить, что это баг компилятора. А так это просто предположение, а точная причина так и не выяснена пока.


На MSVC не работает так же, как у меня

https://godbolt.org/z/ba4Pexz3j
Маньяк Робокряк колесит по городу
Re[7]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 18:00
Оценка:
Здравствуйте, Marty, Вы писали:

R>>Вот когда есть небольшой понятный примерчик, который и там и сям работает, а не работает только на каком-то определенном компиляторе или режиме, вот тогда тогда только можно говорить, что это баг компилятора. А так это просто предположение, а точная причина так и не выяснена пока.


M>На MSVC не работает так же, как у меня

M>https://godbolt.org/z/ba4Pexz3j

А давай, попробуем совсем-совсем упростить?

http://coliru.stacked-crooked.com/a/007b9a0be18537d8

#include <memory>

struct A
{
    A() = default;
    A(A&&) = default;

    A(const A&) = delete;

    static A Create() {return {}; }
};

A makeA() { return {}; }

int main()
{
    const auto sp = std::make_shared<A>(A::Create());
}


Можешь попробовать компильнуть у себя? Если возникнет та же ошибка — тады ой — это однозначно проблема MSVC. Ну а если откомпилится успешно, тогда твое предположение ошибочно, так получается.
--
Отредактировано 07.03.2024 18:02 rg45 . Предыдущая версия . Еще …
Отредактировано 07.03.2024 18:01 rg45 . Предыдущая версия .
Re[7]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: andrey.desman  
Дата: 07.03.24 18:14
Оценка: +1 :)
Здравствуйте, Marty, Вы писали:

M>На MSVC не работает так же, как у меня


Потому что ты, негодяй, не сказал, что есть деструктор.


If no user-defined move constructors are provided for a class type, and all of the following is true:

there are no user-declared copy constructors;
there are no user-declared copy assignment operators;
there are no user-declared move assignment operators;
there is no user-declared destructor.

Then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).

Re[8]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 18:24
Оценка:
Здравствуйте, rg45, Вы писали:


R>Можешь попробовать компильнуть у себя? Если возникнет та же ошибка — тады ой — это однозначно проблема MSVC. Ну а если откомпилится успешно, тогда твое предположение ошибочно, так получается.


Это собралось. Вопрос в том, что не так у меня в том коде, который не компилируется
Маньяк Робокряк колесит по городу
Re[8]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 18:26
Оценка:
Здравствуйте, andrey.desman, Вы писали:

M>>На MSVC не работает так же, как у меня


AD>Потому что ты, негодяй, не сказал, что есть деструктор.


Виноват
И что делать, если деструктор есть? Кроме как явно описать конструктор/оп= перемещения?
Маньяк Робокряк колесит по городу
Re[9]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 19:57
Оценка:
Здравствуйте, Marty, Вы писали:

R>>Можешь попробовать компильнуть у себя? Если возникнет та же ошибка — тады ой — это однозначно проблема MSVC. Ну а если откомпилится успешно, тогда твое предположение ошибочно, так получается.


M>Это собралось. Вопрос в том, что не так у меня в том коде, который не компилируется


Во-о-от! И я о том же. Я тебе прямо очень-очень советую пробовать минимизировать твой код. Причина обязательно найдется, уверяю тебя.
--
Re[9]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 19:58
Оценка:
Здравствуйте, Marty, Вы писали:

M>Виноват

M>И что делать, если деструктор есть? Кроме как явно описать конструктор/оп= перемещения?

Да добавь просто определения-пустышки вместо "default".
--
Re[10]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 20:01
Оценка:
Здравствуйте, rg45, Вы писали:

M>>Виноват

M>>И что делать, если деструктор есть? Кроме как явно описать конструктор/оп= перемещения?

R>Да добавь просто определения-пустышки вместо "default".


Что значит — пустышки?
Маньяк Робокряк колесит по городу
Re[8]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 20:27
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Потому что ты, негодяй, не сказал, что есть деструктор.


AD>

AD>If no user-defined move constructors are provided for a class type, and all of the following is true:

AD> there are no user-declared copy constructors;
AD> there are no user-declared copy assignment operators;
AD> there are no user-declared move assignment operators;
AD> there is no user-declared destructor.

AD>Then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).


Да, но там внизу есть еще такая приписочка:

https://timsong-cpp.github.io/cppwp/n4861/class.copy.ctor#8

[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. — end note]


Так что наличие пользовательского деструктора в базовом классе не должно препятствовать генерации конструктора перемещения в производном классе. Конструктор же перемещения базового класса не объявляется удаленным, он просто не генерируется компилятором. При этом конструктор перемещения производного класса может спокойно воспользоваться конструктором копирования базового. Действительно похоже на баг MSVC, причем характерный для отдельной версии.
--
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.