2009-09-04 37 views
6

Tôi gặp vấn đề nghiêm trọng này. Tôi có một điều tra trong vòng 2 không gian tên như thế này:Xung đột giữa không gian tên và xác định

namespace FANLib { 
namespace ERROR { 

    enum TYPE { 

     /// FSL error codes 
     FSL_PARSER_FILE_IERROR,... 

và ở một nơi khác trong mã của tôi, tôi sử dụng nó như thế này:

FANLib::Log::internalLog(FSLParser::FILE_IERROR, file_ierror, true, FANLib::ERROR::FSL_PARSER_FILE_IERROR); 

Tất cả các biên dịch tốt và tốt, nhưng nếu tôi xảy ra bao gồm " windows.h ", tôi gặp lỗi! Vấn đề nằm trong "WinGDI.h" có dòng này:

#define ERROR    0 

và làm cho trình biên dịch nghĩ rằng, sau FANLib :: ..., có một số không! Các lỗi tôi nhận được là:

Lỗi 1 lỗi C2589: 'liên tục': dấu hiệu bất hợp pháp trên bên phải của '::'

Lỗi 2 lỗi C2059: lỗi cú pháp: '::'

lỗi 3 lỗi C2039: 'FSL_PARSER_FILE_IERROR': không phải là thành viên của '`namespace toàn cầu''

có bất cứ điều gì tôi có thể làm về vấn đề này, mà không cần phải thay đổi không gian tên của tôi do một số suy nghĩ #define? Tôi đã đọc trong một bài đăng khác mà tôi có thể #undef LRI, nhưng làm thế nào an toàn là điều đó?

Trả lời

14

Nói chung, bạn nên tránh sử dụng mã định danh tất cả mũ khi chúng được sử dụng cho macro. Trong trường hợp này, tôi đổi tên vùng tên.

(Như một mặt lưu ý, <windows.h>#define s thứ khác như GetPrinter và thực sự nó được gây phiền nhiễu. Tôi thường đi với #undef sau đó. Nó cũng giúp để chỉ bao gồm <windows.h> trong các tập tin cpp và đảm bảo phạm vi bị ảnh hưởng bởi các tiêu đề càng nhỏ càng tốt.)

+0

Bạn thực hiện một số điểm rất tốt. Thật không may, tôi vẫn chỉ có thể cho câu trả lời của bạn một phiếu bầu. – sbi

+2

Tôi sẽ thêm "quy ước được chấp nhận chuẩn" là các số nhận dạng là tất cả các mũ là các macro. –

+4

Windows.h mất tất cả "quy ước được chấp nhận tiêu chuẩn", ném chúng ra ngoài cửa sổ và khai báo tất cả các macro trên chúng. Nhưng vâng, lời khuyên tốt. Không sử dụng tất cả các mũ cho bất kỳ điều gì khác hơn #defines và không cho phép hiển thị windows.h trong tiêu đề của bạn. – jalf

1

Tôi nghĩ rằng sẽ không thành vấn đề nếu bạn #undef. Nhưng, bạn sẽ phải làm điều đó ở khắp mọi nơi bạn sử dụng cả hai enum của bạn & windows.h. Điều tốt nhất sẽ đổi tên vùng tên của bạn.

2

Đổi tên vùng tên của bạn là giải pháp sạch nhất, an toàn nhất, có khả năng tương tác nhất.

2

Nhảy trên dải "đổi tên không gian tên" của bạn, chỉ đơn giản là vì ERROR là cách quá phổ biến và mơ hồ với tên. Tìm một cái gì đó mô tả hơn.

1

Bạn có thể muốn cấu trúc lại mã của mình để #include chỉ xuất hiện khi cần thiết. Cách "đúng" thậm chí có thể liên quan đến việc tạo các tệp và tiêu đề riêng biệt bao gồm các giao diện cho các hàm bạn sẽ gọi từ windows.h

Tuy nhiên, nếu bạn chỉ muốn sửa chữa đơn giản và lo ngại về tác dụng phụ từ #undef ERROR , chỉ cần xác định lại L ERI sau khi bạn đã hoàn tất khai báo của mình:

 
#undef ERROR 
namespace ERROR { 
#define ERROR 0 

Bạn sẽ phải thực hiện việc này mỗi khi ERROR được nhắc đến (chứ không phải trong một chuỗi).

Có nói rằng, bạn nên ok nếu bạn chỉ đơn giản là không xác định ERROR. Nó sẽ chỉ ảnh hưởng đến cách bộ xử lý tiền xử lý C xử lý ERROR (hay đúng hơn cách nó không) từ điểm đó trở đi.

Nhân tiện, tôi thường thấy tên trong tất cả các chữ in hoa chỉ được sử dụng để chỉ định các hằng số, không dùng cho các loại và không gian tên. Tôi muốn xem xét lại quy ước đặt tên của tôi nếu tôi là bạn ..

+0

Ý tưởng tồi; Microsoft không thể thay đổi # define trong phiên bản SDK mới hơn. Điều này xảy ra ngay cả đối với hằng số (mặc dù ERROR có thể sẽ không bị ảnh hưởng) – MSalters

+0

Bạn nói đúng, nó không thực sự tốt, và sẽ dễ dàng dẫn đến khó sửa lỗi các tác dụng phụ sau này để giả định rằng giá trị của nhãn sẽ luôn là cho hằng số. Nhưng trong phòng thủ của tôi, nó không phải là đề nghị đầu tiên của tôi cũng không phải là lần cuối cùng của tôi, và tôi chưa bao giờ nói bất cứ điều gì về một sửa chữa tốt, tôi nói đó là một sửa chữa đơn giản (hoặc sửa chữa nhanh). tác dụng phụ! – lcv

0

Giải pháp tốt nhất là thay đổi sơ đồ đặt tên của bạn để tránh tất cả mũ, như những người khác đã gợi ý:

namespace FANLib { 
    namespace Error { 
    enum Type { 
     /// FSL error codes 
     FSL_Parser_File_IError, ... 

Ngoài ra giới hạn: định danh đó bắt đầu bằng _ hoặc __. (Nó phức tạp hơn thế, nhưng cuộc sống của bạn sẽ đơn giản hơn nếu bạn chỉ cần tránh tất cả các tên bắt đầu bằng dấu gạch dưới.)

0

Nếu bạn không sử dụng GDI thì bạn có thể xác định NOGDI để chặn các macro xác định trong WinGDI.h. Here bạn có thể tìm thấy các tùy chọn hữu ích khác.

0

Số nhận dạng bắt đầu bằng E và chữ số hoặc E và chữ hoa nên được coi là đã đặt trước, vì các macro mới này có thể được thêm vào <errno.h>.

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