Liên kết các đối tượng C ++ 17, C ++ 14 và C ++ 11 có an toàn không


97

Giả sử tôi có ba đối tượng đã biên dịch, tất cả đều được tạo bởi cùng một trình biên dịch / phiên bản :

  1. A được biên dịch với tiêu chuẩn C ++ 11
  2. B được biên dịch với tiêu chuẩn C ++ 14
  3. C được biên dịch với tiêu chuẩn C ++ 17

Để đơn giản hơn, hãy giả sử tất cả các tiêu đề được viết bằng C ++ 11, chỉ sử dụng các cấu trúc có ngữ nghĩa không thay đổi giữa cả ba phiên bản tiêu chuẩn và vì vậy mọi sự phụ thuộc lẫn nhau đều được thể hiện chính xác với việc bao gồm tiêu đề và trình biên dịch không phản đối.

Sự kết hợp nào của các đối tượng này và không an toàn khi liên kết thành một tệp nhị phân duy nhất? Tại sao?


CHỈNH SỬA: các câu trả lời bao gồm các trình biên dịch chính (ví dụ: gcc, clang, vs ++) được hoan nghênh


6
Không phải là trường học / câu hỏi phỏng vấn. Câu hỏi bắt nguồn từ một trường hợp cụ thể: Tôi đang thực hiện một dự án phụ thuộc vào thư viện mã nguồn mở. Tôi xây dựng thư viện này từ nguồn, nhưng hệ thống xây dựng của nó chỉ chấp nhận một cờ để chọn giữa tòa nhà C ++ 03 / C ++ 11. Tuy nhiên, trình biên dịch tôi sử dụng hỗ trợ các tiêu chuẩn khác và tôi đang xem xét nâng cấp dự án của riêng mình lên C ++ 17. Tôi không chắc liệu đó có phải là một quyết định an toàn hay không. Có thể có sự phá vỡ trong ABI hoặc một số cách khác mà cách tiếp cận không được khuyến khích? Tôi không tìm thấy câu trả lời rõ ràng và quyết định đăng một câu hỏi về trường hợp chung.
ricab

6
Điều này phụ thuộc hoàn toàn vào trình biên dịch. Không có gì trong các đặc tả C ++ chính thức chi phối tình huống này. Cũng có một khả năng nhỏ là mã được viết theo tiêu chuẩn C ++ 03 hoặc C + 11 sẽ có một số vấn đề ở cấp độ C ++ 14 và C ++ 17. Với đủ kiến ​​thức và kinh nghiệm (và mã được viết tốt để bắt đầu), bạn có thể khắc phục bất kỳ vấn đề nào trong số này. Tuy nhiên, nếu bạn chưa quen với các tiêu chuẩn C ++ mới hơn, thì tốt hơn hết bạn nên tuân theo những gì hệ thống xây dựng hỗ trợ và được kiểm tra để hoạt động.
Sam Varshavchik

9
@Someprogrammerdude: Đó là một câu hỏi cực kỳ đáng giá. Tôi ước tôi có một câu trả lời. Tất cả những gì tôi biết là libstdc ++ thông qua RHEL devtoolset tương thích ngược theo thiết kế, bằng cách liên kết tĩnh trong nội dung mới hơn và để lại nội dung cũ hơn để phân giải động trong thời gian chạy bằng cách sử dụng libstdc ++ "bản địa" của bản phân phối. Nhưng điều đó không trả lời câu hỏi.
Các cuộc đua ánh sáng trong quỹ đạo vào

3
@nm: ... mà hầu hết là trường hợp ... khá nhiều người phân phối thư viện C ++ độc lập với phân phối đều làm như vậy (1) ở dạng thư viện động và (2) không có vùng chứa thư viện chuẩn C ++ trên ranh giới giao diện. Các thư viện đến từ bản phân phối Linux rất dễ dàng vì chúng đều được xây dựng với cùng một trình biên dịch, cùng một thư viện tiêu chuẩn và khá nhiều bộ cờ mặc định giống nhau.
Matteo Italia

3
Chỉ để làm rõ nhận xét trước đó từ @MatteoItalia "và khi chuyển từ chế độ C ++ 03 sang C ++ 11 (đặc biệt là std :: string)." Điều này không đúng, việc std::stringtriển khai hoạt động trong libstdc ++ độc lập với -stdchế độ được sử dụng . Đây là một đặc tính quan trọng, chính xác để hỗ trợ các tình huống như OP. Bạn có thể sử dụng mã mới std::stringtrong C ++ 03 và bạn có thể sử dụng mã cũ std::stringtrong C ++ 11 (xem liên kết trong nhận xét sau của Matteo).
Jonathan Wakely

Câu trả lời:


116

Sự kết hợp nào của các đối tượng này và không an toàn khi liên kết thành một tệp nhị phân duy nhất? Tại sao?

Đối với GCC , có thể an toàn khi liên kết với nhau bất kỳ sự kết hợp nào của các đối tượng A, B và C. Nếu tất cả chúng được xây dựng với cùng một phiên bản thì chúng tương thích với ABI, phiên bản tiêu chuẩn (tức là -stdtùy chọn) không tạo ra bất kỳ sự khác biệt nào.

Tại sao? Bởi vì đó là thuộc tính quan trọng trong quá trình triển khai của chúng tôi mà chúng tôi nỗ lực để đảm bảo.

Trường hợp bạn gặp sự cố là nếu bạn liên kết các đối tượng được biên dịch với các phiên bản GCC khác nhau bạn đã sử dụng các tính năng không ổn định từ một tiêu chuẩn C ++ mới trước khi hỗ trợ của GCC cho tiêu chuẩn đó hoàn tất. Ví dụ: nếu bạn biên dịch một đối tượng bằng GCC 4.9 -std=c++11và một đối tượng khác với GCC 5 và -std=c++11bạn sẽ gặp sự cố. Hỗ trợ C ++ 11 là thử nghiệm trong GCC 4.x và do đó có những thay đổi không tương thích giữa các phiên bản GCC 4.9 và 5 của các tính năng C ++ 11. Tương tự, nếu bạn biên dịch một đối tượng với GCC 7 và -std=c++17một đối tượng khác với GCC 8 và -std=c++17bạn sẽ gặp vấn đề, vì hỗ trợ C ++ 17 trong GCC 7 và 8 vẫn đang thử nghiệm và đang phát triển.

Mặt khác, bất kỳ sự kết hợp nào của các đối tượng sau sẽ hoạt động (mặc dù hãy xem lưu ý bên dưới về libstdc++.sophiên bản):

  • đối tượng D được biên dịch với GCC 4.9 và -std=c++03
  • đối tượng E được biên dịch với GCC 5 và -std=c++11
  • đối tượng F được biên dịch với GCC 7 và -std=c++17

Điều này là do hỗ trợ C ++ 03 ổn định trong cả ba phiên bản trình biên dịch được sử dụng và do đó các thành phần C ++ 03 tương thích giữa tất cả các đối tượng. Hỗ trợ C ++ 11 ổn định kể từ GCC 5, nhưng đối tượng D không sử dụng bất kỳ tính năng nào của C ++ 11 và đối tượng E và F đều sử dụng các phiên bản hỗ trợ C ++ 11 ổn định. Hỗ trợ C ++ 17 không ổn định trong bất kỳ phiên bản trình biên dịch nào đã sử dụng, nhưng chỉ đối tượng F sử dụng các tính năng của C ++ 17 và do đó không có vấn đề tương thích với hai đối tượng còn lại (các tính năng duy nhất mà chúng chia sẻ đến từ C ++ 03 hoặc C ++ 11 và các phiên bản được sử dụng làm cho các phần đó trở nên OK). Nếu sau đó bạn muốn biên dịch đối tượng thứ tư, G, sử dụng GCC 8 và -std=c++17sau đó bạn sẽ cần phải biên dịch lại F với cùng một phiên bản (hoặc không liên kết với F) vì các ký hiệu C ++ 17 trong F và G không tương thích.

Cảnh báo duy nhất về khả năng tương thích được mô tả ở trên giữa D, E và F là chương trình của bạn phải sử dụng libstdc++.sothư viện được chia sẻ từ GCC 7 (hoặc mới hơn). Vì đối tượng F được biên dịch với GCC 7, bạn cần sử dụng thư viện được chia sẻ từ bản phát hành đó, vì việc biên dịch bất kỳ phần nào của chương trình với GCC 7 có thể giới thiệu các phần phụ thuộc vào các ký hiệu không có trong libstdc++.soGCC 4.9 hoặc GCC 5. Tương tự, nếu bạn đã liên kết với đối tượng G, được xây dựng bằng GCC 8, bạn sẽ cần sử dụng libstdc++.sotừ GCC 8 để đảm bảo tìm thấy tất cả các ký hiệu mà G cần. Quy tắc đơn giản là đảm bảo thư viện được chia sẻ mà chương trình sử dụng tại thời điểm chạy ít nhất là mới như phiên bản được sử dụng để biên dịch bất kỳ đối tượng nào.

Một lưu ý khác khi sử dụng GCC, đã được đề cập trong phần nhận xét về câu hỏi của bạn, là vì GCC 5 có hai cách triển khaistd::string có sẵn trong libstdc ++. Hai triển khai không tương thích với nhau về liên kết (chúng có các tên bị xáo trộn khác nhau, do đó không thể được liên kết với nhau) nhưng có thể cùng tồn tại trong cùng một tệp nhị phân (chúng có các tên bị ghép khác nhau, vì vậy không xung đột nếu một đối tượng sử dụng std::stringvà sử dụng khác std::__cxx11::string). Nếu các đối tượng của bạn sử dụng std::stringthì thông thường tất cả chúng phải được biên dịch với cùng một chuỗi triển khai. Biên dịch với -D_GLIBCXX_USE_CXX11_ABI=0để chọn gcc4-compatibletriển khai gốc hoặc -D_GLIBCXX_USE_CXX11_ABI=1để chọn cxx11triển khai mới (đừng để bị lừa bởi cái tên, nó cũng có thể được sử dụng trong C ++ 03, nó được gọi làcxx11bởi vì nó tuân theo các yêu cầu C ++ 11). Việc triển khai nào là mặc định phụ thuộc vào cách GCC được định cấu hình, nhưng mặc định luôn có thể được ghi đè tại thời điểm biên dịch với macro.


"bởi vì việc biên dịch bất kỳ phần nào của chương trình với GCC 7 có thể giới thiệu các phụ thuộc vào các ký hiệu có trong libstdc ++. vì vậy từ GCC 4.9 hoặc GCC 5", ý bạn là KHÔNG có từ GCC 4.9 hoặc GCC 5, phải không? Điều này cũng áp dụng cho liên kết tĩnh? Cảm ơn thông tin về khả năng tương thích giữa các phiên bản trình biên dịch.
Hadi Brais

1
Tôi vừa nhận ra một lỗ hổng lớn trong việc đưa ra tiền thưởng cho câu hỏi này. 😂
Lightness Races in Orbit.

4
@ricab Tôi chắc chắn 90% câu trả lời là giống nhau cho Clang / libc ++, nhưng tôi không biết về MSVC.
Jonathan Wakely

1
Câu trả lời này là tuyệt vời. Có tài liệu ở đâu đó rằng 5.0+ là ổn định cho 14/11 không?
Barry

1
Không rõ ràng hoặc ở một nơi. gcc.gnu.org/gcc-5/changes.html#libstdcxxgcc.gnu.org/onlineocs/libstdc++/manual/api.html#api.rel_51 tuyên bố hỗ trợ thư viện cho C ++ 11 là hoàn chỉnh (ngôn ngữ hỗ trợ đã hoàn chỉnh trước đó, nhưng vẫn còn "thử nghiệm"). Hỗ trợ thư viện C ++ 14 vẫn được liệt kê là thử nghiệm cho đến 6.1, nhưng tôi nghĩ trong thực tế không có gì thay đổi giữa 5.x và 6.x ảnh hưởng đến ABI.
Jonathan Wakely

16

Có hai phần cho câu trả lời. Khả năng tương thích ở cấp trình biên dịch và khả năng tương thích ở cấp trình liên kết. Hãy bắt đầu với cái trước.

giả sử tất cả các tiêu đề được viết bằng C ++ 11

Sử dụng cùng một trình biên dịch có nghĩa là cùng một tiêu đề thư viện tiêu chuẩn và các tệp nguồn (các tệp liên kết với trình biên dịch) sẽ được sử dụng bất kể tiêu chuẩn C ++ đích. Do đó, các tệp tiêu đề của thư viện chuẩn được viết để tương thích với tất cả các phiên bản C ++ được hỗ trợ bởi trình biên dịch.

Điều đó nói rằng, nếu các tùy chọn trình biên dịch được sử dụng để biên dịch một đơn vị dịch chỉ định một tiêu chuẩn C ++ cụ thể, thì bất kỳ tính năng nào chỉ có sẵn trong các tiêu chuẩn mới hơn sẽ không thể truy cập được. Điều này được thực hiện bằng cách sử dụng __cpluspluschỉ thị. Xem tệp nguồn vectơ để biết ví dụ thú vị về cách nó được sử dụng. Tương tự, trình biên dịch sẽ từ chối bất kỳ tính năng cú pháp nào được cung cấp bởi các phiên bản mới hơn của tiêu chuẩn.

Tất cả điều đó có nghĩa là giả định của bạn chỉ có thể áp dụng cho các tệp tiêu đề bạn đã viết. Các tệp tiêu đề này có thể gây ra sự không tương thích khi được đưa vào các đơn vị dịch khác nhau nhắm mục tiêu các tiêu chuẩn C ++ khác nhau. Điều này được thảo luận trong Phụ lục C của tiêu chuẩn C ++. Có 4 mệnh đề, tôi sẽ chỉ thảo luận về mệnh đề đầu tiên, và đề cập ngắn gọn đến các mệnh đề còn lại.

C.3.1 Khoản 2: các quy ước từ vựng

Dấu ngoặc kép đơn phân tách một ký tự theo nghĩa đen trong C ++ 11, trong khi chúng là dấu phân tách chữ số trong C ++ 14 và C ++ 17. Giả sử bạn có định nghĩa macro sau trong một trong các tệp tiêu đề C ++ 11 thuần túy:

#define M(x, ...) __VA_ARGS__

// Maybe defined as a field in a template or a type.
int x[2] = { M(1'2,3'4) };

Hãy xem xét hai đơn vị dịch bao gồm tệp tiêu đề, nhưng nhắm mục tiêu C ++ 11 và C ++ 14, tương ứng. Khi nhắm mục tiêu C ++ 11, dấu phẩy trong dấu ngoặc kép không được coi là dấu phân cách tham số; chỉ có một tham số. Do đó, mã sẽ tương đương với:

int x[2] = { 0 }; // C++11

Mặt khác, khi nhắm mục tiêu C ++ 14, các dấu nháy đơn được hiểu là dấu phân tách chữ số. Do đó, mã sẽ tương đương với:

int x[2] = { 34, 0 }; // C++14 and C++17

Vấn đề ở đây là việc sử dụng các dấu ngoặc kép trong một trong các tệp tiêu đề C ++ 11 thuần túy có thể dẫn đến các lỗi đáng ngạc nhiên trong các đơn vị dịch nhắm mục tiêu C ++ 14/17. Do đó, ngay cả khi tệp tiêu đề được viết bằng C ++ 11, nó phải được viết cẩn thận để đảm bảo rằng nó tương thích với các phiên bản sau của tiêu chuẩn. Các __cpluspluschỉ thị có thể hữu ích ở đây.

Ba điều khoản khác từ tiêu chuẩn bao gồm:

C.3.2 Khoản 3: các khái niệm cơ bản

Thay đổi : Bộ phân bổ giao dịch thông thường (không phải vị trí) mới

Cơ sở lý luận : Cần thiết cho phân bổ quy mô.

Ảnh hưởng đến tính năng gốc : Mã C ++ 2011 hợp lệ có thể khai báo một hàm phân bổ vị trí toàn cầu và hàm phân bổ giao dịch như sau:

void operator new(std::size_t, std::size_t); 
void operator delete(void*, std::size_t) noexcept;

Tuy nhiên, trong tiêu chuẩn này, tuyên bố xóa toán tử có thể khớp với xóa toán tử thông thường (không theo vị trí) được xác định trước (3.7.4). Nếu vậy, chương trình không hợp lệ, vì nó dành cho các hàm cấp phát thành viên lớp và các hàm phân bổ đối phó (5.3.4).

C.3.3 Khoản 7: khai báo

Thay đổi : hàm thành viên không tĩnh của constexpr không ngầm định là hàm thành viên const.

Cơ sở lý luận : Cần thiết để cho phép các hàm thành viên constexpr thay đổi đối tượng.

Ảnh hưởng đến tính năng gốc : Mã C ++ 2011 hợp lệ có thể không biên dịch được trong tiêu chuẩn này.

Ví dụ: mã sau hợp lệ trong C ++ 2011 nhưng không hợp lệ trong tiêu chuẩn này vì nó khai báo cùng một hàm thành viên hai lần với các kiểu trả về khác nhau:

struct S {
constexpr const int &f();
int &f();
};

C.3.4 Điều 27: thư viện đầu vào / đầu ra

Thay đổi : được không được xác định.

Cơ sở lý luận : Sử dụng được coi là nguy hiểm.

Ảnh hưởng đến tính năng gốc : Mã C ++ 2011 hợp lệ sử dụng hàm get có thể không biên dịch được trong tiêu chuẩn này.

Sự không tương thích tiềm ẩn giữa C ++ 14 và C ++ 17 được thảo luận trong C.4. Vì tất cả các tệp tiêu đề không chuẩn được viết bằng C ++ 11 (như được chỉ định trong câu hỏi), những vấn đề này sẽ không xảy ra, vì vậy tôi sẽ không đề cập đến chúng ở đây.

Bây giờ tôi sẽ thảo luận về khả năng tương thích ở cấp trình liên kết. Nói chung, các lý do tiềm ẩn cho sự không tương thích bao gồm:

Nếu định dạng của tệp đối tượng kết quả phụ thuộc vào tiêu chuẩn C ++ đích, trình liên kết phải có khả năng liên kết các tệp đối tượng khác nhau. Trong GCC, LLVM và VC ++, điều này may mắn không xảy ra. Có nghĩa là, định dạng của các tệp đối tượng là giống nhau bất kể tiêu chuẩn đích, mặc dù nó phụ thuộc nhiều vào chính trình biên dịch. Trên thực tế, không có trình liên kết nào của GCC, LLVM và VC ++ yêu cầu kiến ​​thức về tiêu chuẩn C ++ đích. Điều này cũng có nghĩa là chúng ta có thể liên kết các tệp đối tượng đã được biên dịch (liên kết tĩnh trong thời gian chạy).

Nếu quy trình khởi động chương trình (hàm gọi main) khác nhau đối với các tiêu chuẩn C ++ khác nhau và các quy trình khác nhau không tương thích với nhau, thì sẽ không thể liên kết các tệp đối tượng. Trong GCC, LLVM và VC ++, điều này may mắn không xảy ra. Ngoài ra, chữ ký của mainhàm (và các hạn chế áp dụng cho nó, xem Phần 3.6 của tiêu chuẩn) là giống nhau trong tất cả các tiêu chuẩn C ++, vì vậy nó tồn tại ở đơn vị dịch nào không quan trọng.

Nói chung, WPO có thể không hoạt động tốt với các tệp đối tượng được biên dịch bằng các tiêu chuẩn C ++ khác nhau. Điều này phụ thuộc vào chính xác giai đoạn nào của trình biên dịch yêu cầu kiến ​​thức về tiêu chuẩn mục tiêu và giai đoạn nào không và tác động của nó đối với việc tối ưu hóa liên thủ tục qua các tệp đối tượng. May mắn thay, GCC, LLVM và VC ++ được thiết kế tốt và không có vấn đề này (không phải tôi biết).

Do đó, GCC, LLVM và VC ++ đã được thiết kế để cho phép khả năng tương thích nhị phân trên các phiên bản khác nhau của tiêu chuẩn C ++. Tuy nhiên, đây không thực sự là một yêu cầu của tiêu chuẩn.

Nhân tiện, mặc dù trình biên dịch VC ++ cung cấp công tắc std , cho phép bạn nhắm mục tiêu một phiên bản cụ thể của tiêu chuẩn C ++, nhưng nó không hỗ trợ nhắm mục tiêu C ++ 11. Phiên bản tối thiểu có thể được chỉ định là C ++ 14, là phiên bản mặc định bắt đầu từ Visual C ++ 2013 Update 3. Bạn có thể sử dụng phiên bản VC ++ cũ hơn để nhắm mục tiêu C ++ 11, nhưng sau đó bạn sẽ phải sử dụng các trình biên dịch VC ++ khác nhau để biên dịch các đơn vị dịch khác nhau nhắm mục tiêu các phiên bản khác nhau của tiêu chuẩn C ++, điều này ít nhất sẽ phá vỡ WPO.

CAVEAT: Câu trả lời của tôi có thể không đầy đủ hoặc rất chính xác.


Câu hỏi thực sự có ý nghĩa liên quan đến liên kết hơn là biên dịch. Tôi nhận ra (nhờ nhận xét này ) có lẽ không rõ ràng và đã chỉnh sửa nó để làm rõ ràng rằng bất kỳ tiêu đề nào được đưa vào đều có cùng cách diễn giải trong cả ba tiêu chuẩn.
ricab

@ricab Câu trả lời bao gồm cả biên dịch và liên kết. Tôi nghĩ bạn đang hỏi về cả hai.
Hadi Brais

1
Thật vậy, nhưng tôi thấy câu trả lời là quá dài và khó hiểu, đặc biệt là cho đến khi "Bây giờ tôi sẽ thảo luận về khả năng tương thích ở cấp trình liên kết". Bạn có thể thay thế mọi thứ ở trên bằng một cái gì đó như nếu các tiêu đề được bao gồm không thể được công nhận là có cùng ý nghĩa trong C ++ 11 và C ++ 14/17, thì sẽ không an toàn khi bao gồm chúng ngay từ đầu . Về phần còn lại, bạn có nguồn nào cho thấy ba gạch đầu dòng đó là lý do duy nhất dẫn đến sự không tương thích không? Cảm ơn cho câu trả lời trong mọi trường hợp, tôi vẫn bỏ phiếu lên
ricab

@ricab Tôi không thể nói chắc chắn. Đó là lý do tại sao tôi thêm phần báo trước vào cuối câu trả lời. Bất kỳ ai khác đều được hoan nghênh mở rộng câu trả lời để làm cho nó chính xác hoặc đầy đủ hơn trong trường hợp tôi bỏ sót điều gì đó.
Hadi Brais

Điều này làm tôi bối rối: "Sử dụng cùng một trình biên dịch có nghĩa là cùng một tiêu đề thư viện chuẩn và các tệp nguồn (...) sẽ được sử dụng". Làm thế nào có thể là trường hợp? Nếu tôi đã biên dịch mã cũ bằng gcc5, thì 'tệp trình biên dịch' thuộc về phiên bản đó không thể là bằng chứng trong tương lai. Đối với mã nguồn được biên dịch vào (cực kỳ) các thời điểm khác nhau với các phiên bản trình biên dịch khác nhau, chúng ta có thể chắc chắn rằng tiêu đề thư viện và tệp nguồn là khác nhau. Với quy tắc của bạn rằng chúng phải giống nhau, bạn phải biên dịch lại mã nguồn cũ hơn với gcc5, ... và đảm bảo rằng tất cả chúng đều sử dụng 'tệp trình biên dịch' mới nhất (giống nhau).
user2943111

2

Các tiêu chuẩn C ++ mới bao gồm hai phần: các tính năng ngôn ngữ và các thành phần thư viện tiêu chuẩn.

Như bạn muốn nói về tiêu chuẩn mới , những thay đổi trong chính ngôn ngữ (ví dụ: ranged-for) hầu như không có vấn đề gì (đôi khi xung đột tồn tại trong tiêu đề thư viện của bên thứ 3 với các tính năng ngôn ngữ tiêu chuẩn mới hơn).

Nhưng thư viện tiêu chuẩn ...

Mỗi phiên bản trình biên dịch đi kèm với việc triển khai thư viện tiêu chuẩn C ++ (libstdc ++ với gcc, libc ++ với clang, thư viện tiêu chuẩn MS C ++ với VC ++, ...) và chính xác một triển khai, không nhiều thực thi cho mỗi phiên bản tiêu chuẩn. Ngoài ra, trong một số trường hợp, bạn có thể sử dụng cách triển khai khác của thư viện chuẩn ngoài trình biên dịch được cung cấp. Điều bạn nên quan tâm là liên kết việc triển khai thư viện tiêu chuẩn cũ hơn với một thư viện mới hơn.

Xung đột có thể xảy ra giữa thư viện của bên thứ ba và mã của bạn là thư viện chuẩn (và các thư viện khác) liên kết đến thư viện của bên thứ ba đó.


"Mỗi phiên bản trình biên dịch đi kèm với một thực hiện STL" Không họ không
Lightness Races ở Orbit

@LightnessRacesinOrbit Ý của bạn là không có sự kết hợp nào giữa ví dụ: libstdc ++ và gcc?
E. Vakili

8
Không, ý tôi là STL đã lỗi thời chỉ hơn hai mươi năm. Ý bạn là Thư viện chuẩn C ++. Đối với phần còn lại của câu trả lời, bạn có thể cung cấp một số tài liệu tham khảo / bằng chứng để hỗ trợ cho yêu cầu của bạn không? Tôi nghĩ đối với một câu hỏi như thế này thì điều đó rất quan trọng.
Lightness Races in Orbit,

3
Xin lỗi, không, nó không rõ ràng từ văn bản. Bạn đã đưa ra một số khẳng định thú vị, nhưng vẫn chưa sao lưu chúng với bất kỳ bằng chứng nào.
Lightness Races in Orbit,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.