我正在使用 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 扩展时产生问题。
当您使用
gcc
时,它只是 clang
的同义词。您的 C++ 代码被编译为 C++,但像 C 一样链接。这就是您的错误的来源。您可以显式链接已有的 C++ 库,也可以使用 g++
或 clang++
,它们是编译器的 C++ 前端。
当你在 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 设置中进行全局调整。