2010-04-28 28 views
18

Giúp giải quyết cuộc tranh luận đang diễn ra trong các nhận xét tại this question about bool and 1:Trình tiền xử lý C++ # định nghĩa một từ khóa. Các tiêu chuẩn có phù hợp không?

Trình xử lý tiền chuẩn C++ phù hợp cho phép sử dụng #define để xác định lại từ khóa ngôn ngữ? Nếu vậy, phải có một bộ tiền xử lý C++ chuẩn phù hợp cho phép điều này?

Nếu chương trình C++ xác định lại từ khóa ngôn ngữ, chính chương trình đó có thể là tiêu chuẩn phù hợp không?

+0

Tôi khá chắc chắn tôi đã nhìn thấy điểm cuối cùng tranh luận ở đây, nhưng về mặt C99. – Potatoswatter

Trả lời

20

Trong C++, điều gần gũi nhất với cấm #define ing một từ khóa là §17.4.3.1.1/2, mà chỉ không cho phép nó trong một đơn vị dịch thuật bao gồm một tiêu đề thư viện tiêu chuẩn:

Một đơn vị dịch bao gồm tiêu đề sẽ không chứa bất kỳ macro nào xác định tên được khai báo hoặc xác định trong tiêu đề đó. Cũng không phải đơn vị dịch như vậy sẽ xác định các macro cho các tên tương tự như từ khóa.

Câu thứ hai của đoạn đó đã được thay đổi trong C++ 0x để hoàn toàn cấm #define ing một từ khóa (C++ 0x FCD §17.6.3.3.1):

Một bản dịch đơn vị không đượC#define hoặC#undef tên từ từ giống hệt nhau.

Edit: Như đã chỉ ra bởi Ken Bloom trong comments to his answer, các quy tắc đã không thay đổi trong C++ 0x; văn bản vừa được sắp xếp lại để gây nhầm lẫn cho những người như tôi. :-)

+4

Vì vậy, về mặt kỹ thuật, trong C++ 03 nó là hợp pháp để xác định lại từ khóa, * miễn là bạn không bao gồm một tiêu đề duy nhất *? Tôi nghĩ rằng tôi sẽ giải thích nó như là "định nghĩa lại các từ khóa bị cấm", như C++ 0x nói. :) – jalf

+0

Điều này trả lời câu hỏi liệu một chương trình định nghĩa lại các từ khóa là các tiêu chuẩn phù hợp, không phải là khả năng kỹ thuật của bộ tiền xử lý. –

+0

@Ken: Phải. Tuy nhiên, nếu một chương trình vi phạm tuyên bố đó, thì chương trình sẽ không thành công vì quy tắc có thể chẩn đoán được (nghĩa là quy tắc không có nghĩa là "không cần chẩn đoán" và không nói rằng vi phạm sẽ dẫn đến hành vi không xác định).Vì vậy, tôi nghĩ rằng một bộ tiền xử lý phù hợp ít nhất là cần thiết để cảnh báo rằng bạn đang vi phạm quy tắc. –

5

Làm việc từ 2005-10-19 C++ working draft (vì tôi không có một tiêu chuẩn tiện dụng):

Mục 16.3 định nghĩa ngữ pháp cho #define#define identifier replacement-list-newline (macro đối tượng tương tự) hoặc một trong nhiều công trình xây dựng bắt đầu với #define identifier lparen (macro giống chức năng). identifier s được định nghĩa trong phần 2.10 là identifier-nondigit | identifier identifier-nondigit | identifier digit. Phần 2.11 chỉ ra rằng một danh sách nhất định các số nhận dạng được coi là điều kiện vô điều kiện trong giai đoạn 7 của phần biên dịch (phần 2.1) và tôi kết luận rằng chúng không được xử lý đặc biệt trong giai đoạn 4, đó là phần mở rộng tiền xử lý. Vì vậy, có vẻ như tiêu chuẩn yêu cầu bộ tiền xử lý cho phép bạn xác định lại các từ khóa ngôn ngữ (được liệt kê trong Phần 2.11).

Tuy nhiên, bộ tiền xử lý có một từ khóa riêng, cụ thể là defined, cũng như danh sách các macro được xác định trước (Mục 16.8). Phần 16.8 quy định rằng hành vi không xác định nếu bạn xác định lại các hành vi này, nhưng không ngăn cản trình tiền xử lý nhận ra chúng dưới dạng tên macro.

+1

Cũng lưu ý rằng các số nhận dạng 'true' và' false' (vì không có "từ khóa" nào, chúng chỉ là "số nhận dạng") được xử lý đặc biệt trong khi thay thế macro. –

+0

@James: bạn có thể chỉ ra phần trong tiêu chuẩn (hoặc bản nháp) mà nó nói điều này không? Việc thực hiện GCC cũng yêu cầu xử lý các toán tử có tên của C++ (các toán tử '# defined' trong iso646.h trong C) đặc biệt khi hoạt động trong chế độ C++. http://gcc.gnu.org/onlinedocs/cpp/Macros.html –

+0

@Ken: "Sau khi tất cả thay thế do mở rộng macro và toán tử đơn nhất được xác định đã được thực hiện, tất cả các từ định danh và từ khóa còn lại, ngoại trừ' true' và 'false', được thay thế bằng số pp 0" (16.1/4). Đối với lý do tại sao các toán tử được đặt tên được xử lý đặc biệt, đó là bởi vì toán tử được đặt tên là mã thông báo tiền xử lý "toán tử hoặc dấu chấm câu", không phải là mã thông báo tiền xử lý "định danh". –

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