You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1 Mac下CMake构建C++程序无法捕获异常问题求助

问题解决:M1 MacBook上CMake构建C++23程序无法捕获异常

问题重现

在M1 MacBook上使用Clang 17/Apple Clang + CMake 3.28构建C++23程序时,程序无法捕获std::runtime_error,触发trace trap崩溃;但直接用clang++ -std=c++23 except.cpp othertu.cpp编译可正常捕获异常并输出内容。改用GCC构建则无问题。

测试代码如下:

CMakeLists.txt

cmake_minimum_required(VERSION 3.26)
project(doesntwork VERSION 0.0.0.1)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_executable(test except.cpp othertu.cpp)

except.cpp(主函数)

#include <print>
#include <iostream>
#include <stdexcept>
#include "otherheader.h"

int main() {
  try {
    int x = 0;
    std::cin >> x;
    magic ma(x);
  } catch (std::runtime_error const& e) {
    std::println("{}", e.what());
  }
}

otherheader.h

#include <print>

void maythrow();

class magic{
  public:
  magic(int x);
};

othertu.cpp

#include "otherheader.h"

void maythrow() {
  // 不存在test.txt文件,因此该函数总会抛出异常
  // 这么写是为了避免编译器优化掉相关代码
  std::ifstream file{"test.txt", std::ios::binary};
  if (file) {
    std::println("good");
  } else {
    throw std::runtime_error{"bad"};
  }
}

magic::magic(int x) {
  if (x > 1) {
      maythrow();
  }
}

原因分析

CMake在Apple Silicon平台的默认编译配置中,Release模式下会默认启用-fno-exceptions选项,直接禁用了C++异常处理机制;而直接使用clang++编译时,默认会启用-fexceptions(异常支持),因此可以正常捕获异常。此外,othertu.cpp中缺失<fstream>和<stdexcept>头文件,虽然直接编译可能因间接包含侥幸通过,但属于未定义行为,可能加剧CMake构建时的异常问题。

解决方案

方案1:显式启用异常支持

在CMakeLists.txt中添加编译选项,强制开启异常支持:

cmake_minimum_required(VERSION 3.26)
project(doesntwork VERSION 0.0.0.1)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 显式开启C++异常支持
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
# 针对Release模式单独设置(如果需要保留Release优化)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fexceptions")

add_executable(test except.cpp othertu.cpp)

方案2:强制使用Debug模式构建

Debug模式下CMake默认不会禁用异常,你可以在构建时指定:

cmake .. -DCMAKE_BUILD_TYPE=Debug
make

或者在CMakeLists.txt开头直接设置:

set(CMAKE_BUILD_TYPE Debug)

方案3:修复头文件缺失问题

在othertu.cpp中补充缺失的头文件,避免未定义行为:

#include "otherheader.h"
#include <fstream>   // 用于std::ifstream
#include <stdexcept> // 用于std::runtime_error

验证步骤

  1. 修改上述文件后,删除原构建目录(rm -rf build)
  2. 重新执行构建命令:
    mkdir build && cd build
    cmake ..
    make
    
  3. 运行程序并输入大于1的整数,此时应正常捕获异常并输出bad。

内容的提问来源于stack exchange,提问作者suspiciously_large_carrot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:01:29