macOS Majave 10.14.5下使用gcc的报错记录

it2022-05-05  175

macOS Majave 10.14.5下使用gcc的报错记录

2019年7月18日

正文

这两天在复习C++的知识,就想在mac上写几个简单的程序跑一跑。从来没有试过macOS上的gcc,这次正好体验一下。

程序test.cpp如下:

#include<iostream> using namespace std; class Box { public: // define the creation function Box(double i = 2.0, double b = 2.0, double h = 2.0) { cout << "Constructor called." << endl; length = i; breadth = b; height = h; } double Volume() { return length * breadth * height; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; int main() { Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 Box *ptrBox; // save the address of box1 ptrBox = &Box1; // try to call the Volume() function of box1 cout << "Volume of Box1: " << ptrBox->Volume() << endl; // save the address of box2 ptrBox = &Box2; // try to call the Volume() function of box1 cout << "Volume of Box2: " << ptrBox->Volume() << endl; return 0; }

这是一个从教程上拷贝的程序,非常简单,一个Box类,用指针指向对象。

之前有在Ubuntu上用gcc编译c程序的经验,于是我打开Terminal就是一个:

gcc test.py -o test

于是出来下面这一堆玩意:

Undefined symbols for architecture x86_64: "std::__1::locale::use_facet(std::__1::locale::id&) const", 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 test-bef777.o 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 test-bef777.o "std::__1::ios_base::getloc() const", 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 test-bef777.o 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 test-bef777.o "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)", 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 test-bef777.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 test-bef777.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 test-bef777.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 test-bef777.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 test-bef777.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 test-bef777.o "std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(double)", referenced from: _main in test-bef777.o "std::__1::cout", referenced from: _main in test-bef777.o Box::Box(double, double, double) in test-bef777.o "std::__1::ctype<char>::id", 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 test-bef777.o 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 test-bef777.o "std::__1::locale::~locale()", 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 test-bef777.o 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 test-bef777.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 test-bef777.o "std::__1::ios_base::clear(unsigned int)", 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 test-bef777.o "std::terminate()", referenced from: ___clang_call_terminate in test-bef777.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 test-bef777.o ___clang_call_terminate in test-bef777.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 test-bef777.o "___gxx_personality_v0", 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 test-bef777.o 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 test-bef777.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 test-bef777.o Dwarf Exception Unwind Info (__eh_frame) in test-bef777.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

我也看不懂这错误是什么意思,一开始以为是缺少了什么文件。那么会缺少什么文件呢,可能是头文件吧,于是百度了一下解决方案,尝试了这个链接中的方法。在Terminal中输入以下,重新安装macOS SDK:

xcode-select --install

这边可以参考这个链接中的答案。

完事以后我重新运行了一遍编译命令,结果开始报相同的错误。于是我又搜索了一下,发现不是缺失头文件的问题。真正的原因是gcc在编译cpp时默认链接的是c的标准库。这个链接中的回答比较详细了:

This is the case even with the old 4.2 GCC (I experienced this when I set up my unofficial iOS toolchain). gcc assumes C by default, and invokes the linker without linking to the C++ standard library; in contrast, g++ assumes C++ and links against the C++ standard library by default.

翻译一下,大意就是,这个问题出现在旧版本的4.2的gcc中。gcc默认的语言是c,所以它在编译的时候不会链接到C++标准库。而g++则相反,它默认是c++,所以会默认链接到C++标准库。

所以在编译的时候,只需要以下命令就可以了:

gcc -lstdc++ test.cpp -o test

或者使用g++:

g++ test.cpp -o test

我按照上述方法运行了一下,得到了正确的输出:

MacBook-Pro:Desktop xxx$ gcc -lstdc++ test.cpp -o test MacBook-Pro:Desktop xxx$ ./test Constructor called. Constructor called. Volume of Box1: 5.94 Volume of Box2: 102

补充材料

gcc是啥,参考链接。 gcc和g++的区别,参考链接。


最新回复(0)