Visual Studio:如何测试在代码/static_assert 中是否启用了编译器选项

问题描述

我想在代码中检查是否在编译时设置了某些选项。

具体来说,我已经实现了一些异常处理,并希望使用 static_assert 来确保在 Visual Studio 编译器中设置了 /EHa 选项。 (我使用的是 2017 和 2019 并启用了 C++Latest)

我的解决方案有 54 个项目,每个项目有 4 个配置......很容易错过一个。 或者...如果未设置该选项,我可能希望代码不同....

非常感谢

解决方法

当我使用这些选项时,我确实发现编译器已经为此发出警告:warning C4535: calling _set_se_translator() requires /EHa

我查看了 VS 标头中函数的属性或装饰器,因此我可以直接将其移植到我的代码中,但找不到任何东西。

到目前为止,我已经决定在代码中添加注释,以便其他开发人员查看何时发出警告。

// Save & Restore the Structured Exception Handler
// Set our own handler during the call
class Scoped_SE_Translator
{
private:
    const _se_translator_function old_SE_translator;
public:
    Scoped_SE_Translator() = delete;
    Scoped_SE_Translator(_se_translator_function new_SE_translator) noexcept :  // NOTE: Compiler option /EHa is required  ("Enable C++ Exception" = "Yes with SEH Exceptions")
        old_SE_translator{_set_se_translator(new_SE_translator)} { }
    ~Scoped_SE_Translator() noexcept { _set_se_translator(old_SE_translator); }
};

我还在现有的 solution.props 文件中设置了项目默认值:

  <ItemDefinitionGroup>
    <ClCompile>
      <ExceptionHandling>Async</ExceptionHandling>
      <FloatingPointExceptions>true</FloatingPointExceptions>
      <TreatSpecificWarningsAsErrors>4535;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
    </ClCompile>
  </ItemDefinitionGroup>

但是,这取决于开发人员在新的 vcxproj 文件中添加一行:

<Import Project="$(SolutionDir)SolutionSettings.props" />

我不确定是否有更“有力”的方法来确保新项目具有“正确”的默认设置。

,

我建议您可以使用 [预定义宏(https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-160)。

_CPPUNWIND:如果 /GX(启用异常处理)、/clr(公共语言运行时编译)或 /EH 中的一个或多个,则定义为 1 (异常处理模型)编译器选项已设置。否则, 未定义。

此外,您可以参考有关 To set this compiler option programmatically 的 Microsoft Docs。

此外,您还可以使用代码来确定是否启用了 /EHa。例如:

inline bool CodeHasEHaSwitch()
{
    bool dtorCalled = false;

    struct CCheckEHaSwitch
    {
        CCheckEHaSwitch( bool& dtorCalled) : dtorCalled( dtorCalled ) {}
        ~CCheckEHaSwitch() {  dtorCalled = true; }
        bool& dtorCalled;

        static void Win32ExceptionTranslator( unsigned int nExceptionCode,EXCEPTION_POINTERS *pExceptionInfo )
        {  throw nExceptionCode; }
    };

    _se_translator_function pfnPrevSeTranslator =
        _set_se_translator( CCheckEHaSwitch::Win32ExceptionTranslator );
    try
    {
        CCheckEHaSwitch test( dtorCalled );

        *((int*)0) = 0;  // generate access violation
    }
    catch (unsigned int)
    {
    }

    _set_se_translator( pfnPrevSeTranslator );

    return dtorCalled;
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...