一、背景
由于在不同操作系统上学习和使用C++时,环境不同,操作结果会产生差异。
我在mac上写了一个最简单的 c++ 程序,源码如下:
/* hello.cpp*/ #include <iostream> int main(int argc, char *argv[]){ std::cout << "hello world" << std::endl; return(0); }% |
编译代码:gcc hello.cpp
编译时报错,报错如下
二、报错信息
jie@A-MacBookPro c-test % gcc hello.cpp Undefined symbols for architecture arm64: "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from: std::__1::ctype<char> const& std::__1::use_facet<std::__1::ctype<char> >(std::__1::locale const&) in hello-3ecbb1.o "std::__1::ios_base::getloc() const", referenced from: std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in hello-3ecbb1.o "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)", referenced from: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(unsigned long, char) in hello-3ecbb1.o "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from: std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in hello-3ecbb1.o "std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char)", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in hello-3ecbb1.o "std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in hello-3ecbb1.o "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in hello-3ecbb1.o "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in hello-3ecbb1.o "std::__1::cout", referenced from: _main in hello-3ecbb1.o "std::__1::ctype<char>::id", referenced from: std::__1::ctype<char> const& std::__1::use_facet<std::__1::ctype<char> >(std::__1::locale const&) in hello-3ecbb1.o "std::__1::locale::~locale()", referenced from: std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in hello-3ecbb1.o "std::__1::ios_base::__set_badbit_and_consider_rethrow()", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in hello-3ecbb1.o "std::__1::ios_base::clear(unsigned int)", referenced from: std::__1::ios_base::setstate(unsigned int) in hello-3ecbb1.o "std::terminate()", referenced from: ___clang_call_terminate in hello-3ecbb1.o "___cxa_begin_catch", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in hello-3ecbb1.o ___clang_call_terminate in hello-3ecbb1.o "___cxa_call_unexpected", referenced from: std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::failed() const in hello-3ecbb1.o std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::ostreambuf_iterator(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in hello-3ecbb1.o "___cxa_end_catch", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in hello-3ecbb1.o "___gxx_personality_v0", referenced from: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in hello-3ecbb1.o std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in hello-3ecbb1.o std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::failed() const in hello-3ecbb1.o std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::ostreambuf_iterator(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in hello-3ecbb1.o std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in hello-3ecbb1.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) |
大致提示是 ld链接代码有问题:ld: symbol(s) not found for architecture arm64
三、解决方案
换成 :g++ hello.cpp
四、原因
4.1 首先看下gcc 和 g++ 的版本
gcc版本
jie@A-MacBookPro c-test % gcc --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 Apple clang version 13.0.0 (clang-1300.0.29.3) Target: arm64-apple-darwin21.2.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin |
g++版本
jie@A-MacBookPro c-test % g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 Apple clang version 13.0.0 (clang-1300.0.29.3) Target: arm64-apple-darwin21.2.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin |
从以上两个命令的版本信息结果看出,输出结果都是一样的。那为什么会出现使用gcc 报错,g++又可以的。这就要从gcc的历史说起。
gcc时GNU开发的针对c的编译器,刚开始只支持编译c代码,随着gcc的发展愈发强大,后面gcc也支持编译c++、Objective-c和java等,在编译时需要通过设定参数指定编译的语言。所以后来,gcc默认编译的是c代码。把参数给用户设置显然没有那么友好,于是就专门针对c++ 开发了g++编译器。
所以gcc是一个编译器集合,而g++是针对c++的编译器。
因此,想要使用gcc编译c++的代码需要加上参数 -lstdc++ 指令即可。
例:gcc -lstdc++ hello.cpp
说明:-l 表示链接 std c++标准库。