2013-02-16 45 views
6

Trong C++ 11 khi một chỉ thị tiền xử lý của mẫu ...Bao gồm điều kiện trong C++ 11 với chữ được người dùng xác định?

#if expr 

... đang gặp phải, expr được đánh giá là một constant-expression như mô tả trong 16.1 [cpp.cond].

này được thực hiện sau khi thay thế vĩ mô trên expr, định danh của nó (và từ khóa) được thay thế bằng 0, preprocessing-tokens của nó được chuyển đổi thành tokens, defined điều hành được đánh giá, và vân vân.

Câu hỏi của tôi là điều gì sẽ xảy ra khi một trong các mã thông báo trong expruser-defined-literal?

Các chữ cái do người dùng định nghĩa giống như các cuộc gọi chức năng, nhưng các cuộc gọi chức năng không thể xảy ra trong expr (Tôi nghĩ), như là một tác dụng phụ của việc thay thế số nhận dạng. Tuy nhiên về mặt kỹ thuật, user-defined-literals có thể tồn tại.

Tôi nghi ngờ đó là lỗi, nhưng tôi hoàn toàn không thể thấy cách kết luận điều đó từ tiêu chuẩn?

Có lẽ tác động (pedantic) của việc thêm các chữ người dùng được xác định theo điều 16 [cpp] đơn giản là bị bỏ qua?

Hoặc tôi có thiếu gì đó không?

Cập nhật:

Để làm rõ bằng một ví dụ:

gì preprocess này để:

#if 123_foo + 5.5 > 100 
bar 
#else 
baz 
#endif 

thanh hoặc baz hoặc là nó lỗi?

GCC 4.7 báo cáo:

test.cpp:1:5: error: user-defined literal in preprocessor expression 

nên nó nghĩ rằng nó là một lỗi. Điều này có thể được biện minh với tham chiếu đến tiêu chuẩn không? Hay đây chỉ là "ngầm"?

+0

Khái niệm tiền xử lý của "biểu thức liên tục" hoàn toàn khác với C++, tôi tin. Bạn thực sự chỉ có thể sử dụng các chữ và macro mở rộng thành chữ cuối cùng ... ít nhất đó là cách tôi luôn hiểu nó. –

+0

Có vẻ như phiên bản g ++ của bạn thiếu thứ gì đó, không phải bạn. –

+1

Tôi nghi ngờ đó là ý định của ủy ban để cho phép loại điều này, vì logic của tiền xử lý và ngữ nghĩa ngôn ngữ luôn luôn tách biệt nhau. Nhưng vâng, tiêu chuẩn dường như ngụ ý nó nên được xử lý. – aschepler

Trả lời

3

Trong C++ 11 khi chỉ thị tiền xử lý của biểu mẫu ... gặp phải, expr được đánh giá là constant-expression như được mô tả trong 16.1 [cpp.cond].

này được thực hiện sau khi thay thế vĩ mô trên expr, định danh của nó (và từ khóa) là thay thế bằng 0, preprocessing-tokens của nó được chuyển đổi thành tokens, defined điều hành được đánh giá, và vân vân.

Câu hỏi của tôi là điều gì sẽ xảy ra khi một trong số tokens trong expruser-defined-literal?

Chương trình không đúng định dạng.

Cốt lõi của đối số của tôi được thu thập từ quan sát trong 16.1/1 chú thích 147, trong giai đoạn dịch 4 không có identifiers trừ tên macro.

Đối số:

Theo 2.14.8 [lex.ext]/2

Một user-defined-literal được coi là một cuộc gọi đến một literal operator hoặc literal operator template(13.5.8).

Vì vậy, ở đây chúng tôi có một cuộc gọi còn lại cho một (toán tử) chức năng ngay cả sau khi tất cả các thay thế được mô tả trong 16.1/4. (Nỗ lực khác, ví dụ sử dụng một hàm constexpr, sẽ cản trở bởi sự thay thế của tất cả các phi vĩ mô identifiers bởi 0.)

Như này xảy ra trong giai đoạn dịch 4, có không chức năng xác định hoặc thậm chí tuyên bố chưa; một tra cứu cố gắng của literal-operator-id phải không thành công (xem chú thích 147 trong 16.1/1 cho một đối số tương tự).

Từ một góc độ hơi khác nhau, nhìn vào 5.19/2 chúng ta thấy:

Một conditional-expression là một core constant expression trừ khi nó liên quan đến một trong các cách sau như một subexpression có khả năng đánh giá (3.2) [...]:

  • [...]
  • yêu cầu hàm không phải là hàm tạo constexpr cho một lớp chữ hoặc hàm constexpr;
  • yêu cầu hàm constexpr không xác định hoặc hàm tạo constexpr không xác định [...];

Từ đó, sử dụng một user-defined literal trong một constant expression đòi hỏi một định nghĩaconstexprliteral operator, mà lại không thể có mặt trong giai đoạn dịch 4.

gcc là quyền từ chối điều này.

0

Trong C++ 11 khi gặp phải chỉ thị tiền xử lý của biểu mẫu #ifdef expr, expr được đánh giá là biểu thức không đổi như mô tả 16.1. Điều này được thực hiện sau khi thay thế macro trên expr, các từ định danh (và từ khóa) của nó được thay thế bằng 0, các mã tiền xử lý của nó được chuyển thành mã thông báo, toán tử được định nghĩa được đánh giá, v.v.

Không!

Đối số cho #ifdef, #ifndef hoặc definedkhông phải được đánh giá. Ví dụ: giả sử tôi không bao giờ là #define biểu tượng tiền xử lý SYMBOL_THAT_IS_NEVER_DEFINED. Điều này hoàn toàn hợp lệ:

#ifdef SYMBOL_THAT_IS_NEVER_DEFINED 
code 
#endif 

Mở rộng biểu tượng không được xác định là bất hợp pháp.Đây là bất hợp pháp giả định SYMBOL_THAT_IS_NEVER_DEFINED chưa được xác định:

#if SYMBOL_THAT_IS_NEVER_DEFINED 
code 
#endif 

Tương tự như kiểm tra xem một con trỏ là không null trước khi dereferencing nó, kiểm tra xem một biểu tượng được xác định trước khi sử dụng nó là hợp pháp:

#if (defined SYMBOL_THAT_MIGHT_BE_DEFINED) && SYMBOL_THAT_MIGHT_BE_DEFINED 
code 
#endif 
+0

Xin lỗi tôi đã đánh máy trong câu hỏi, ý tôi là '#if expr', không phải' #ifdef expr'. Tôi đã sửa câu hỏi, vui lòng điều chỉnh câu trả lời của bạn một cách thích hợp. –

+0

Cũng lưu ý rằng 'expr' trong câu hỏi của tôi đại diện cho một loạt các mã thông báo khớp với' biểu thức hằng số' - và không phải là mã định danh duy nhất 'expr'. –

+0

Xem "Cập nhật" trong câu hỏi –

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