Tôi đang thử nghiệm khả năng hiển thị biểu tượng C++ trên Linux và gcc. Dường như cách ưa thích là sử dụng -fvisibility = hidden và xuất các biểu tượng được sử dụng từng cái một theo trang wiki có khả năng hiển thị gcc (http://gcc.gnu.org/wiki/Visibility). Vấn đề của tôi là nhiều thư viện không xử lý tốt điều này, họ quên xuất biểu tượng rõ ràng, đây là một vấn đề nghiêm trọng. Sau một số lỗi cố định, ngay cả một số phần của tăng có thể vẫn bị ảnh hưởng. Tất nhiên những lỗi đó nên được sửa, nhưng cho đến khi tôi muốn sử dụng một cách "an toàn" để ẩn càng nhiều càng tốt các biểu tượng càng tốt.Khả năng hiển thị biểu tượng và không gian tên
Tôi đã đưa ra một giải pháp: Tôi đặt tất cả các ký hiệu trong không gian tên và tôi sử dụng thuộc tính ẩn biểu tượng trên đó và xuất giao diện công khai, theo cách này chỉ có biểu tượng của tôi mới bị ảnh hưởng.
Vấn đề là tôi nhận được thông báo cảnh báo khi tôi biên dịch nội dung nào đó đối với thư viện đó cho mọi lớp mà tôi chưa xuất và tôi sử dụng trong ứng dụng làm trường lớp.
namespace MyDSO __attribute__ ((visibility ("hidden"))) {
struct Foo {
void bar() __attribute__ ((visibility ("default"))) {}
};
}
struct Bar {
MyDSO::Foo foo;
};
int main() {}
Thông báo cảnh báo có thể được sao chép trong ví dụ nhỏ này, nhưng tất nhiên không gian tên phải nằm trong thư viện lớp khác trong ứng dụng.
$ gcc-4.7.1 namespace.cpp -o namespace
namespace.cpp:7:8: warning: ‘Bar’ declared with greater visibility than the type of its field ‘Bar::foo’ [-Wattributes]
Như tôi hiểu tầm nhìn biểu tượng, ẩn namespace nên có hiệu lực thi hành khá giống với sử dụng -fvisibility = ẩn, nhưng tôi không bao giờ nhận được những cảnh báo tương tự sử dụng sau này. Tôi thấy rằng khi tôi vượt qua -fvisibility = ẩn cho ứng dụng, lớp trong ứng dụng cũng sẽ bị ẩn, vì vậy tôi sẽ không nhận được cảnh báo. Nhưng khi tôi không vượt qua tùy chọn, không có biểu tượng nào trong các tiêu đề dường như bị ẩn với trình biên dịch, vì vậy tôi sẽ không nhận được cảnh báo nữa.
Đề xuất của thông báo cảnh báo này là gì? Đây có phải là vấn đề nghiêm trọng không? Trong trường hợp nào điều này có thể gây ra bất kỳ vấn đề nào? Làm thế nào ẩn không gian tên là khác nhau để fvisibility = ẩn?
Cảm ơn câu trả lời chi tiết của bạn. Chỉ vì tò mò, tôi quan tâm đến những gì các trình biên dịch cần trình biên dịch mà không thể được tạo ra? Theo như tôi biết trong các lớp tầm thường, ngay cả typeinfo có thể được tạo ra. Khi sử dụng vis = hidden, bạn sẽ không nhận được cảnh báo ngay cả khi bạn ẩn các biểu tượng không được ẩn, bạn chỉ nhận được lỗi biểu tượng không xác định từ trình liên kết. Sử dụng gcc không gian tên ẩn có thể phát hiện sự cố. Có thể có sử dụng hợp pháp để chỉ xuất một số biểu tượng trong một lớp, nhưng gcc phát ra cảnh báo. Mô-đun C++ của Doug Gregor rất thú vị, tôi thích bài thuyết trình của anh ấy, cảm ơn bạn đã chia sẻ nó. – VargaD
Trong ngắn hạn, typeinfo cho bất kỳ lớp nào với một virtual luôn luôn được phát ra, trong khi typeinfo cho các lớp không có chỉ được phát ra khi typeid() hoặc một cái gì đó sử dụng nó (exception catches, dynamic_cast <> etc) được sử dụng. Ngoài ra, hầu hết các trình biên dịch phát ra hai hoặc nhiều hơn các hàm tạo của hàm xây dựng cho mỗi hàm dựng sẵn của chương trình, và có một số phép thuật trong thế hệ phá hủy nữa. Trong ngắn hạn, -fvisibility = ẩn giấu rất nhiều, và phương pháp của bạn sẽ chỉ ẩn các công cụ lập trình cụ thể và không phải là ma thuật internals. Phần lớn điều này bắt đầu trở nên dễ dàng hơn với các Mô-đun C++, mặc dù không được giải quyết. Niall –