为什么我在 MacBook Air M2 中编译 C/C++ 代码时每次最后都要写“-lstdc++”?

问题描述 投票:0回答:2

我正在使用 MacBook Air M2,我是新机器。我发现MacBook中有clang,它默认直接用于MacBook中的C和C++代码。 但是当我用像

这样的简单行编译代码时,我的系统遇到了一个问题或某种问题
gcc 1931D.cpp -o 1931D

它给了我这样的错误:

Undefined symbols for architecture arm64:
  "std::logic_error::logic_error(char const*)", referenced from:
      std::length_error::length_error[abi:ue170006](char const*) in 1931D-f28fab.o
  "std::length_error::~length_error()", referenced from:
      std::__1::__throw_length_error[abi:ue170006](char const*) in 1931D-f28fab.o
  "std::bad_array_new_length::bad_array_new_length()", referenced from:
      std::__throw_bad_array_new_length[abi:ue170006]() in 1931D-f28fab.o
  "std::bad_array_new_length::~bad_array_new_length()", referenced from:
      std::__throw_bad_array_new_length[abi:ue170006]() in 1931D-f28fab.o
  "std::__1::basic_istream<char, std::__1::char_traits<char>>::operator>>(long long&)", referenced from:
      _main in 1931D-f28fab.o
      solve() in 1931D-f28fab.o
      solve() in 1931D-f28fab.o
      solve() in 1931D-f28fab.o
      solve() in 1931D-f28fab.o
  "std::__1::cin", referenced from:
      _main in 1931D-f28fab.o
      solve() in 1931D-f28fab.o
      solve() in 1931D-f28fab.o
  "std::terminate()", referenced from:
      ___clang_call_terminate in 1931D-f28fab.o
  "typeinfo for std::length_error", referenced from:
      std::__1::__throw_length_error[abi:ue170006](char const*) in 1931D-f28fab.o
  "typeinfo for std::bad_array_new_length", referenced from:
      std::__throw_bad_array_new_length[abi:ue170006]() in 1931D-f28fab.o
  "vtable for std::length_error", referenced from:
      std::length_error::length_error[abi:ue170006](char const*) in 1931D-f28fab.o
   NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "operator delete(void*)", referenced from:
      std::__1::allocator<long long>::deallocate[abi:ue170006](long long*, unsigned long) in 1931D-f28fab.o
      void std::__1::__libcpp_operator_delete[abi:ue170006]<void*>(void*) in 1931D-f28fab.o
  "operator new(unsigned long)", referenced from:
      std::__1::allocator<long long>::allocate[abi:ue170006](unsigned long) in 1931D-f28fab.o
      void* std::__1::__libcpp_operator_new[abi:ue170006]<unsigned long>(unsigned long) in 1931D-f28fab.o
  "___cxa_allocate_exception", referenced from:
      std::__1::__throw_length_error[abi:ue170006](char const*) in 1931D-f28fab.o
      std::__throw_bad_array_new_length[abi:ue170006]() in 1931D-f28fab.o
  "___cxa_begin_catch", referenced from:
      ___clang_call_terminate in 1931D-f28fab.o
  "___cxa_call_unexpected", referenced from:
      std::__1::vector<long long, std::__1::allocator<long long>>::max_size() const in 1931D-f28fab.o
      std::__1::vector<long long, std::__1::allocator<long long>>::__base_destruct_at_end[abi:ue170006](long long*) in 1931D-f28fab.o
      std::__1::allocator<long long>::deallocate[abi:ue170006](long long*, unsigned long) in 1931D-f28fab.o
  "___cxa_free_exception", referenced from:
      std::__1::__throw_length_error[abi:ue170006](char const*) in 1931D-f28fab.o
  "___cxa_throw", referenced from:
      std::__1::__throw_length_error[abi:ue170006](char const*) in 1931D-f28fab.o
      std::__throw_bad_array_new_length[abi:ue170006]() in 1931D-f28fab.o
  "___gxx_personality_v0", referenced from:
      /private/var/folders/pt/csddh2cd0fq4krbz3vjkgf7m0000gn/T/1931D-f28fab.o
**ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)**

但是,当我使用下面的代码时,它可以正常工作,因为我提供了 C++ 文件的参考链接,我想是这样。

gcc 1931D.cpp -o 1931D -lstdc++

您能告诉我为什么我的电脑上会出现这种情况吗?有什么办法可以避免这种情况吗

另外,如果你能告诉我如何在 MacBook Air m2 中重置整个 C++ 或编译器(gcc),那么这将非常有帮助?

我尝试了这个

gcc 1931D.cpp -o 1931D -lstdc++
,它工作正常,但是,为什么我必须写“-lstdc++”。而且它也会在使用 vsCode 及其 cpp 扩展时产生问题。

c++ c compiler-construction clang vscode-extensions
2个回答
0
投票

当您使用

gcc
时,它只是
clang
的同义词。您的 C++ 代码被编译为 C++,但像 C 一样链接。这就是您的错误的来源。您可以显式链接已有的 C++ 库,也可以使用
g++
clang++
,它们是编译器的 C++ 前端。


0
投票

当你在 MacBook 上编译 C++ 代码时,尤其是在 ARM64 架构的 M1 或 M2 芯片上,直接使用

gcc
有时不会自动链接到 C++ 标准库,从而导致未定义符号错误遇到过。使用
-lstdc++
标志成功编译代码的原因是,这明确告诉编译器链接到 GNU 标准 C++ 库,从而解决与 C++ 功能相关的未定义符号。

clang
编译器是 macOS 上的默认编译器,为了兼容性,它将
gcc
别名为
clang
。但是,
clang
使用标准库 (
libc++
) 的 LLVM 实现,而不是 GNU 版本的
libstdc++
。因此,当您编译 C++ 代码时,使用
clang++
g++
(如果已安装)作为编译器命令而不是
gcc
更合适。这会自动链接到正确的 C++ 标准库,从而无需使用
-lstdc++
标志。

要在 MacBook Air M2 上编译 C++ 代码而不需要显式链接标准库,您应该使用:

clang++ 1931D.cpp -o 1931D

或者如果您安装了

g++

g++ 1931D.cpp -o 1931D

这种方法应该可以解决链接问题,这就是为什么添加

-lstdc++
可以解决使用
gcc
时的问题(实际上是 macOS 上的
clang
)。

关于重置 C++ 编译器或 MacBook Air M2 上的整个开发设置,macOS 没有内置方法将编译器“重置”为其默认状态,因为它是命令行工具包的一部分。如果您遇到问题,可以重新安装命令行工具或将其更新到最新版本。要删除然后重新安装命令行工具,您可以在终端中使用以下命令:

sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install

这将删除当前安装的命令行工具并提示您再次安装它们。

对于 VS Code 及其 C++ 扩展的问题,确保将 VS Code 配置设置为使用正确的编译器(例如,对于 C++ 文件,使用

clang++
g++
而不是
gcc
)应该会有所帮助。您可以在项目的
tasks.json
文件夹内的
.vscode
文件中或在 VS Code 设置中进行全局调整。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.