2009-01-22 20 views
14

Cảnh báo này có phải lo lắng về điều gì không? Tôi đã đọc rằng nó có thể gây ra hành vi thất thường?Cảnh báo C4099: loại tên được nhìn thấy lần đầu tiên bằng cách sử dụng 'lớp' bây giờ nhìn thấy bằng cách sử dụng 'struct' (MS VS 2k8)

Đó là một ví dụ tôi đang cố gắng biên dịch, ai đó có thể giải thích cho tôi lý do tại sao tác giả tuyên bố đối tượng là lớp nhưng sau đó gõ vào cấu trúc? Có hoàn toàn bình thường nếu làm như vậy nếu lớp học là POD?

Cảm ơn.

Trả lời

23

Cảnh báo này xuất hiện khi bạn có một tuyên bố loại mâu thuẫn với một loại khác (một nói là "lớp", câu hỏi kia nói "struct"). Với quy tắc định nghĩa một, tất cả các khai báo ngoại trừ nhiều nhất là một khai báo chuyển tiếp. Cảnh báo nói chung sẽ chỉ ra rằng một tờ khai chuyển tiếp của một loại là sai và thường là một lỗi đánh máy đơn giản và cần được sửa. Trong trường hợp này không nên có tác dụng phụ, nhưng bạn thực sự nên sửa chữa nó. Tuy nhiên, có thể có một số điều rất khó chịu xảy ra nếu bạn có xung đột tên loại (có thể do sử dụng mệnh đề "sử dụng không gian tên" hoặc ô nhiễm không gian tên toàn cầu). Những cảnh báo này có thể chỉ ra rằng bạn đang trộn tiêu đề từ hai thư viện khác nhau và tên loại có xung đột. Mã được biên dịch trong các điều kiện này có thể làm một số điều rất bất ngờ.

Lời khuyên của tôi - hiểu lý do cảnh báo xuất hiện và khắc phục. Nếu cảnh báo nằm trong sản phẩm của bên thứ ba, hãy nhấn mạnh rằng họ sẽ khắc phục.

+0

Lời khuyên tuyệt vời, cảm ơn. –

+2

MS Mangling Scheme tại http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling#Data_Type: 'union' được mã hóa thành' T', 'struct' thành' U' và 'class' là' V' . –

+0

Xin cảm ơn! , tôi có thể tìm thấy một cấu trúc typedef ..., khiến tôi cảnh báo này. – HadesDX

1

Mặc dù điều này được coi là thực hành không tốt, tôi nghĩ sẽ không có vấn đề gì khi kết hợp định nghĩa lớp và khai báo cấu trúc vì chúng về cơ bản là cùng một kiểu dữ liệu. Sự khác biệt chính là cấu trúc các thành viên là theo mặc định công cộng, trái với các thành viên lớp học là tư nhân, nhưng nếu không bố trí bộ nhớ là giống hệt nhau.

+1

Có thể xấu trên trình biên dịch với các thuật toán mangling tên khác nhau. – MSalters

0

Trong C++ chỉ có khác biệt giữa một lớp và cấu trúc là các thành viên và hàm của lớp là riêng tư theo mặc định, trong khi cấu trúc theo mặc định là công khai; vì vậy, thực tế là lớp học là POD không nên tạo sự khác biệt ở đây.
Tôi đoán rằng cảnh báo này đến từ việc bảo trì mã (định nghĩa được cập nhật ở đâu đó nhưng không ở đâu đó khác) và sửa mã để cảnh báo biến mất (ví dụ: sử dụng lớp trong typedef).

4

Chỉ để đưa nhận xét của MSalters về số this đăng ở trên lên cấp cao nhất. Tôi đã có một số khó khăn để tìm lỗi linker như là kết quả của VC bằng cách sử dụng từ khóa 'lớp' hoặc 'struct' trong mangling của nó của tên.

Nếu bạn không nghĩ rằng đó là vấn đề, bạn có thể bị gãi đầu trong nhiều giờ!

1

Richard Corden là chính xác - có lý do MS có cảnh báo này. Các tên trang trí (xoài) bao gồm tên khóa (cấu trúc hoặc lớp) tên kiểu là. Nếu một hàm hoặc phương thức nhận đối tượng nào đó là đối số hoặc trả về đối tượng được tham chiếu ở đâu đó khi khóa lớp sai hiển thị, bạn sẽ không nhận được lỗi biên dịch nhưng trình liên kết sẽ khiếu nại vì tên trang trí khác nhau. Lỗi trình liên kết chỉ hiển thị biểu tượng mà nó đang tìm kiếm và dễ dàng bỏ qua khóa không khớp ở lớp đó, vì vậy cảnh báo trình biên dịch chi tiết hơn, sớm hơn là có giá trị. Nó vẫn có thể là hai phiên bản không xuất hiện trong cùng một đơn vị biên dịch, tất nhiên, và bạn có thể sẽ gãi đầu trong một thời gian nếu bạn tin rằng sự khác biệt duy nhất là khả năng hiển thị thành viên mặc định.

+0

Điều này vẫn đúng trên các trình biên dịch MSVC mới hơn? Hoặc là 'lớp' và' struct' thực sự tương đương với tên mangling bây giờ? –

2

Tôi thảo luận cảnh báo này sâu trong bài đăng trên blog của tôi "Is C4099 really a sillywarning?". Kết luận của tôi là tốt nhất là tắt. :-) Tốt, ít nhất là đối với tôi.

1

Một điều tôi đã thấy có thể gây ra cảnh báo này đang cố gắng #import tệp .tlb từ một DLL trong khi cũng có cùng DLL làm tham chiếu trong dự án của bạn. Tôi chỉ cố định một vấn đề với điều này bằng cách loại bỏ các DLL như là một tài liệu tham khảo từ bên trong dự án của tôi.

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