Không phải argc * 0
cũng không argc - argc
là các biểu thức không đổi, chuyển đổi lvalue thành rvalue được cho phép trong một số trường hợp nhất định không có trường hợp nào áp dụng ở đây. Nếu chúng ta nhìn vào dự thảo phần tiêu chuẩn C++ 11 5.19
[expr.const], nó đưa ra các ngoại lệ. Nó nói:
Một điều kiện thể hiện là một biểu thức hằng lõi trừ khi nó liên quan đến một trong các cách sau như một subexpression khả năng đánh giá [...]
và có một số viên đạn bao gồm sau đây trên chuyển đổi lvalue-to-rvalue:
chuyển đổi lvalue thành rvalue (4.1) trừ khi nó được áp dụng cho
một glvalue của thiếu hoặc liệt kê kiểu đó đề cập đến một đối tượng const non-volatile có một trước khởi, khởi tạo với một biểu thức hằng số, hoặc
một glvalue loại đen đó đề cập đến một đối tượng non-volatile định nghĩa với constexpr, hoặc đề cập đến một đối tượng phụ của một đối tượng đó, hoặc
một glvalue loại đen đó đề cập đến một đối tượng tạm thời không bay hơi mà tuổi thọ không phải là đã kết thúc, được khởi tạo với một biểu thức không đổi;
Thật thú vị khi lưu ý rằng gcc không chấp nhận đoạn mã sau (see it live):
constexpr int a = argc * 2;
Vì vậy, nó trông giống như gcc đang nói tôi biết kết quả sẽ là zero và do đó nó thực hiện xếp liên tục và nó không cần phải thực hiện chuyển đổi lvalue-to-rvalue của argc
để xác định kết quả.
Rất tiếc, tôi không thấy bất kỳ điều khoản nào trong phần 5.19
cho phép loại ngắn mạch này. Điều này trông rất giống với trường hợp trong int a=1, is a || 1 a constant expression? có báo cáo lỗi nhưng không ai trong nhóm gcc đã trả lời câu hỏi đó. Tôi đã thêm một comment vào báo cáo lỗi cho biết điều này có vẻ liên quan.
bình luận của Mark dưới đây cho thấy đây là một lỗi:
Có cả C++ - trì hoãn gấp chi nhánh trên mà một số nhà phát triển gcc đang làm việc, trong đó sẽ trì hoãn một số tối ưu hóa và có thể sửa lỗi này. Điều quan trọng vì các lý do khác, việc từ chối mã trong câu hỏi này là ưu tiên rất thấp
Các biểu thức liên tục yêu cầu mọi biểu thức con phải là biểu thức không đổi? Không, ví dụ từ 5.19
nó nói: (nhấn mạnh tôi)
Một điều kiện thể hiện là một biểu thức hằng lõi trừ khi nó liên quan đến một trong các cách sau như một subexpression khả năng đánh giá (3.2), nhưng subexpressions của logic AND (5.14), logic OR (5,15), và có điều kiện (5,16) hoạt động mà không phải là đánh giá không được coi là [...]
Vì vậy, sau đây là một biểu thức hằng:
constexpr int a = false && argc * 0;
Vì argc * 0
không được đánh giá vì &&
đánh giá từ trái sang phải và ngắn mạch.
Tôi nghĩ cả hai trường hợp này nên bị từ chối do [expr.const]/2: 'argc' không phải là biểu thức liên tục cốt lõi vì nó liên quan đến chuyển đổi từ rvalue sang rvalue của biến không được khởi tạo với hằng số biểu hiện. –
Bây giờ tôi đã có cơ hội để suy nghĩ về điều này trông giống như [int a = 1, là || 1 một biểu thức liên tục?] (Http://stackoverflow.com/q/31526278/1708801) –