DEV Community

Kevin Albertson
Kevin Albertson

Posted on

"Specify /EHsc" warning

Using cmake to build C++ with custom CMAKE_CXX_FLAGS on MSVC may result in a warning to Specify /EHsc.

Here is an example:

# CMakeLists.txt

cmake_minimum_required (VERSION 3.23)
project(ehsc)
add_executable(ehsc ehsc.cpp)
Enter fullscreen mode Exit fullscreen mode
// ehsc.cpp
#include <iostream>

class NeedsDestruction {
public:
    NeedsDestruction () {
        std::cout << "Constructor called" << std::endl;
    }

    ~NeedsDestruction () {
        std::cout << "Destructor called" << std::endl;
    }
};

void throws () {
    NeedsDestruction nd;
    throw std::exception("exception");
}

int main () {
    try {
        throws ();
    } catch (std::exception e) {
        std::cout << "caught exception" << std::endl;
    }
}
Enter fullscreen mode Exit fullscreen mode

Configure with a custom CMAKE_CXX_FLAGS:

cmake -S. -Bcmake-build -DCMAKE_CXX_FLAGS="/Wall"
cmake --build cmake-build --target ehsc
Enter fullscreen mode Exit fullscreen mode

Building results in many warnings suggesting to Specify /EHsc:

warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
Enter fullscreen mode Exit fullscreen mode

Why does specifying CMAKE_CXX_FLAGS result in this warning? Because cmake specifies default flags for MSVC.
Setting CMAKE_CXX_FLAGS appears to have the side-effect of overwriting the default MSVC flags set by cmake.
For example, if CMAKE_CXX_FLAGS is not set, this is the output of printing CMAKE_CXX_FLAGS with cmake 3.23.1 on my Windows machine:

CMAKE_CXX_FLAGS=/DWIN32 /D_WINDOWS /W3 /GR /EHsc
Enter fullscreen mode Exit fullscreen mode

Excluding /EHsc from the build flags appears particularly problematic. /EHsc is the documented default for the exception handling model:

Use an /EH compiler option to specify the exception handling model to use in a C++ project. Standard C++ exception handling (/EHsc) is the default in new C++ projects in Visual Studio.

Without /EHsc, the destructor in the example is not called when the exception is thrown. Executing does not print the expected Destructor called:

throws ... begin
Constructor called
caught exception
Enter fullscreen mode Exit fullscreen mode

Top comments (0)