MSVC интерпретирует аргумент структуры только для перемещения как указатель - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть простая структура, состоящая из одного члена, с удаленной конструкцией / назначением копии и конструкцией / назначением перемещения по умолчанию. Я пытаюсь передать одну из этих структур в функцию по значению и вернуть член - довольно просто.

struct NoCopy {
    explicit NoCopy(int x) : x{x} {}

    NoCopy(const NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;

    NoCopy(NoCopy&&) = default;
    NoCopy& operator=(NoCopy&&) = default;

    int x;
};

// noinline to ensure the crash is reproducible in release
// not required to reproduce the problem code
__declspec(noinline) int problem_function(NoCopy x) {
    return x.x;
}

int main() {
    return problem_function(NoCopy{ 1 });
}

Проблема в том, что при компиляции с MSVC эта функция падает.

Глядя на разборку, выясняется, что при удалении конструктора копирования MSVC пытается интерпретировать x, как если бы он был NoCopy*, и последующее чтение элемента вызывает ошибку сегментации.

Вот пример Godbolt с gcc и clang для справки: https://godbolt.org/z/jG7kIw

Обратите внимание, что и gcc, и clang ведут себя как положено. Также обратите внимание, что это происходит как в оптимизированных, так и в неоптимизированных сборках, и, похоже, влияет как на MSVC 2015, так и на 2017 год.

Для справки, я компилирую на своем компьютере с Visual Studio Professional 2015 (14.0.25431.01 обновление 3) - и я в основном тестирую сборки x64. Мой набор инструментов платформы для аварийного воспроизведения установлен на v140.

Итак, мой вопрос: есть ли разумные объяснения этому или я смотрю на ошибку компилятора.

edit: я отправил отчет об ошибке здесь

edit # 2: Если, как и я, вы столкнулись с похожей проблемой и не можете легко обновить VS - похоже, что определение конструктора перемещения / оператора присваивания вручную вместо использования = default вызывает MSVC выкладывает правильный код на сайт вызова и избегает сбоев. вот новый крестник

по этой причине такие вещи, как std :: unique_ptr, похоже, не затрагиваются. Размер структуры также является фактором.

1 Ответ

0 голосов
/ 01 ноября 2018

Я не вижу, как это что-то, кроме вопиющей ошибки компилятора. Код действителен.

Может показаться странным, что что-то столь фундаментальное уже сломано в двух версиях MSVS, но если бы мне пришлось догадываться, это произошло бы из-за относительно новой поддержки C ++ 17 elision. (Конечно, в данном случае я использую термин «поддержка» несколько свободно).

(ошибка ОП в сети Интернет здесь . )

...