Почему этот код, использующий __LINE__, компилируется под MSV C в режиме выпуска, но не в режиме отладки? - PullRequest
19 голосов
/ 13 июля 2020

Рассмотрим эту программу:

#include <iostream>

template<bool Debug = false, int Line = __LINE__>
constexpr int adds(const int& a, const int& b) { 
    if (Debug)
        std::cout << __FUNCTION__ << " called on line " << Line << '\n';
    return (a + b);
}

int main() {
    std::cout << adds(3, 7) << '\n';
    std::cout << adds<true, __LINE__> (5, 9) << '\n';
    return 0;
}

Когда я пытаюсь скомпилировать и собрать ее в режиме Debug, Visual Studio 2017 генерирует следующие ошибки компилятора:

1>------ Build started: Project: Simulator, Configuration: Debug x64 ------
1>main2.cpp
1>c:\***\main2.cpp(12): error C2672: 'adds': no matching overloaded function found
1>c:\***\main2.cpp(12): error C2975: 'Line': invalid template argument for 'adds', expected compile-time constant expression
1>c:\***\main2.cpp(3): note: see declaration of 'Line'
1>Done building project "Simulator.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Однако, когда Я пробую это в режиме Release: он компилирует, строит, запускает и выдает соответствующий результат:

10
adds called on line 12
14

Это потенциальная ошибка Visual Studio 2017? Если нет, то почему он работает в одном режиме, а не в другом?

Вы можете увидеть его скомпилированный здесь: Compiler Explorer


Вот копия флаги командной строки для режимов отладки и выпуска:

Отладка

/JMC /permissive- /GS /W3 /Zc:wchar_t /Qspectre /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc141.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++latest /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Simulator.pch" /diagnostics:classic 

Выпуск

/permissive- /GS /GL /W3 /Gy /Zc:wchar_t /Qspectre /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc141.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /std:c++latest /FC /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\Simulator.pch" /diagnostics:classic 

1 Ответ

22 голосов
/ 13 июля 2020

Похоже, что сообщалось: __LINE__ не может использоваться в качестве аргумента для функций constexpr .

У нас есть известная ошибка для этой проблемы в команде C ++ здесь . [...] Мы определили, что эта проблема не является ошибкой. Пожалуйста, обратитесь к комментариям Джонатана.

И Джонатан говорит:

Это побочный эффект поддержки компиляторами Edit-and-Continue (в основном мы этого не делаем) Я не хочу, чтобы изменение значения __LINE__ считалось «грубым» редактированием, которое подавляет Edit-and-Continue): если вы компилируете с /Zi вместо /ZI, тогда код должен компилироваться (но исполняемый файл не поддерживает Edit-and-Continue). [...] Ошибка считается функцией ...

Из MSV C docs :

Вариант /ZI похож на /Zi, но создает файл PDB в формате, который поддерживает функцию «Изменить и продолжить». [...] Параметр /ZI также несовместим с использованием предопределенного макроса __LINE__; код, скомпилированный с помощью /ZI, не может использовать __LINE__ в качестве аргумента шаблона, не являющегося типом, хотя __LINE__ можно использовать в расширениях макросов.

Однако, когда я пробую это в режиме выпуска: он компилирует, строит, запускает и выдает соответствующий результат:

Я думаю, причина в /ZI vs /Zi разница флагов. Ваши флаги режима выпуска имеют /Zi, поэтому он компилируется нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...