2011-01-26 116 views
6

Tôi đang biên soạn một dự án bằng Cygwin (GCC v4.5.0) và tôi đang gặp một vấn đề liên kết lẻ. Tôi hy vọng ai đó với một số chuyên môn có thể giúp đỡ.Thư viện C++ std liên kết với các tiêu chuẩn C++ khác nhau

Error: undefined reference to std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)

Tuy nhiên, liên kết chỉ thất bại khi tôi biên dịch với trình biên dịch gcc cờ: -std=c++0x Nó thành công khi tôi không xác định tiêu chuẩn.

Một số lưu ý:

  1. tôi thông báo cho gcc để liên kết các thư viện chuẩn bằng tay với các trình biên dịch cờ: -lstdc++
  2. Các phụ thuộc biểu tượng có nguồn gốc từ một tập tin tiêu đề thư viện Boost (v.1.45.0) : boost::units::detail::utility.hpp, function: std::string demangle(const char* name);
  3. Biên dịch và liên kết ứng dụng đúng cách bằng cách sử dụng MinGW gcc v4.5.0.

Câu hỏi:

  1. Có thư viện chuẩn biên soạn thường chứa các ký hiệu khác nhau cho các tiêu chuẩn khác nhau C++?
  2. Tên mangling của các biểu tượng có thay đổi với các tiêu chuẩn C++ khác nhau trong GCC không?
  3. Tại sao người liên kết không thể tìm thấy các biểu tượng cho std::basic_string khi tôi có thể đảm bảo rằng nó có thể tìm thấy libstdc++.a?

Cảm ơn mọi người trước.

-JT

+0

Có điều gì đó sai trái với văn bản lỗi của bạn. Bạn đã trích dẫn nó trực tiếp? Nó không có ý nghĩa gì cả. –

+0

@Noah: Bạn đang đề cập đến "&&"? Nó trông giống như ký hiệu tham chiếu rvalue từ C++ 0x. –

Trả lời

8

Có, cả bản sửa đổi mới và báo cáo kỹ thuật đều có nhiều thay đổi đối với nội dung của thư viện chuẩn. Hàm bạn đã tham chiếu (std::string 'Hàm khởi tạo di chuyển ') mới được thêm vào trong thư viện chuẩn của C++ 0x.

Phiên bản của tiêu chuẩn không ảnh hưởng đến tên mangling, mặc dù phiên bản trình biên dịch và trình biên dịch mới hơn là cần thiết để hỗ trợ C++ 0x tốt hơn, vì vậy nó có vẻ liên quan.

Có thể bạn đang sử dụng phiên bản libstdC++ quá cũ.

EDIT: xử lý sự cố cơ bản:

$ find /usr -name libstdc++.a 
/usr/lib/gcc/i686-pc-cygwin/4.5.0/libstdc++.a 

$ cygcheck -f /usr/lib/gcc/i686-pc-cygwin/4.5.0/libstdc++.a 
libstdc++6-devel-4.5.0-1 

$ nm -C /usr/lib/gcc/i686-pc-cygwin/4.5.0/libstdc++.a | grep basic_string | grep '&&' 
00000000 T std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) 
00000000 T std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) 
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::assign(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::operator=(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 

này thực sự trông hơi buồn cười. Các định nghĩa cho std::wstring (ví dụ: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >) trông chính xác, các phiên bản thu hẹp thì không. Tên std::string không bao giờ nên tồn tại trong giai đoạn mangling, vì nó chỉ là một typedef.

Tuy nhiên, tôi nhận được đầu ra tương tự trên linux:

% find /usr -name libstdc++.a 
/usr/lib64/gcc/x86_64-pc-linux-gnu/3.4.6/libstdc++.a 
/usr/lib64/gcc/x86_64-pc-linux-gnu/3.4.6/32/libstdc++.a 
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.2/libstdc++.a 
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.2/32/libstdc++.a 

% nm -C /usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.2/libstdc++.a | grep basic_string | grep '&&' 
0000000000000000 W std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) 
0000000000000000 W std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) 
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::assign(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::operator=(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&) 
+0

Hmm .. để cho biết rằng có lẽ phiên bản Cygwin của GCC v.4.5.0 là thiếu sót? –

+1

Khi bạn cài đặt phiên bản thử nghiệm của g ++, bạn có nhận được v4.5 của 'libstdC++ 6-devel' không? Chỉ cần thêm vào câu trả lời của tôi các lệnh cần thiết để kiểm tra phiên bản đó. –

+1

Ahh sửa lỗi đó. Cảm ơn rất nhiều Ben. Tôi đã không cài đặt libstdC++ 6-devel. Thật không may là Cygwin không cung cấp thêm tài liệu để làm cho quá trình ít bị lỗi hơn. –

Các vấn đề liên quan