2011-07-17 49 views
8

Giả sử có ba tiêu đề AAA.h, BBB.hMyLib.h. MyLib.h cần bao gồm cả AAA.hBBB.h để hoạt động bình thường.Có cách nào để phát hiện khi phụ thuộc tệp "vô tình" thỏa mãn không?

Bây giờ, nó chỉ xảy ra rằng BBB.h cũng bao gồm AAA.h trong đó, nhưng điều này là do thực hiện, một chi tiết mà MyLib.h không cần phải quan tâm.

Tuy nhiên, do nhầm lẫn, nhà văn của MyLib.h bị bỏ qua bao gồm AAA.h và không bao giờ thông báo. Điều này thường không dẫn đến lỗi hoặc cảnh báo, theo như tôi biết. Sau đó, ai đó thay đổi chi tiết triển khai của BBB.h để không còn cần đến AAA.h và do đó bị xóa. Bây giờ MyLib không biên dịch vì nội bộ của thư viện BBB đã thay đổi.

Có cách nào để báo lỗi hoặc cảnh báo trong các trường hợp như thế này không? Tôi nghi ngờ (nếu điều này thậm chí có thể) rằng nó sẽ mất một số loại chú thích trong tiêu đề được bao gồm.

+1

Bạn nói đúng, nó sẽ yêu cầu chú thích, vì đôi khi tiêu đề được * ghi lại * để bao gồm các tiêu đề khác hoặc tiêu đề được triển khai bên trong bằng cách bao gồm các tệp khác. Bạn sẽ không muốn lội qua rất nhiều các kết quả sai vì mã của bạn dựa vào một cái gì đó được định nghĩa trong '/ compiler/internals/stl_vector_impl.h', khi tất cả ứng dụng của bạn là' ', hoặc nơi thư viện do người dùng định nghĩa đã theo sau một tổ chức tương tự. –

+1

GCC có tùy chọn để xem tiêu đề nào bao gồm các tiêu đề nào: http://stackoverflow.com/questions/5258826/how-to-see-the-actual-order-of-include-files-after-preprocessing/5258938# 5258938 –

Trả lời

2

Tôi nghĩ tốt nhất nên tránh tùy thuộc vào các tiêu đề khác trong tiêu đề giao diện công khai, do đó vấn đề này không xuất hiện.

Tiêu đề giao diện công cộng không được chứa các định nghĩa không cần thiết.

Có nhiều thủ thuật khác nhau để thực hiện mọi việc mà không bao gồm tệp. Ví dụ: bạn có thể khai báo các thẻ cấu trúc theo cách thủ công nếu bạn chỉ cần một con trỏ (thư viện chỉ xác định typedef thất vọng) và bạn có thể sử dụng _Bool thay vì bool để tránh <stdbool.h>. Rất tiếc, nhiều loại quan trọng như size_tuint32_t chỉ được xác định trong tiêu đề.

Một số gói đi xa để xác định foo_uint32_t của riêng chúng bằng cách định cấu hình để chúng không cần bao gồm <stdint.h> trong tiêu đề giao diện công khai của chúng. Điều này khá phức tạp vì các loại phải giống hệt nhau để tránh nhầm lẫn: ngay cả khi sizeof(unsigned int) == sizeof(unsigned long) == 4 chúng là các loại khác nhau. Vì vậy, nó có thể không có giá trị nó.

2

Bạn đang minh họa lý do tại sao các tiêu đề đều là phương thức nhập không gian tên.

Giải pháp duy nhất tôi thấy là kỷ luật. Các hàm thư viện chuẩn yêu cầu bạn bao gồm tiêu đề thích hợp, các dự án của bạn nên áp dụng cùng một tiêu chuẩn. Các tiêu đề như MyLib.h chỉ nên chứa các loại mà nó xác định và nguyên mẫu hàm của nó. Nếu cần phải sử dụng một loại nhất định để thực hiện công việc, tiêu đề phải được bao gồm rõ ràng, vì vậy nếu cần định nghĩa từ AAA, cần bao gồm AAA.h và nếu cần định nghĩa từ BBB thì phải bao gồm BBB.h, tương tự như bất kỳ tệp triển khai nào (giả sử MyLib.c) nên bao gồm rõ ràng tất cả các tiêu đề cho bất kỳ định nghĩa nào nó sử dụng, bất kể chắc chắn rằng MyLib.h cũng bao gồm chúng. Không bao giờ giả định rằng tiêu đề xác định bất kỳ điều gì ngầm ngụ ý bằng cách bao gồm các tiêu đề khác.

Điều này có thể dễ dàng kiểm tra bằng IDE, thông thường sẽ cho bạn biết tên được xác định và do đó bạn có thể dễ dàng tìm ra bao gồm tệp để sử dụng. Có thể có các công cụ có sẵn để thực hiện loại kiểm tra này.

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