2016-05-18 31 views
12

Tại sao tôi không gặp lỗi khi cố gắng tạo mảng có kích thước âm?Không có lỗi đối với mảng có kích thước âm

#include <array> 

int main() 
{ 
    std::array<int, -1> arr; 
} 

Tôi không gặp lỗi. Hành vi này có dự định không?

+2

Những biên dịch bạn đang sử dụng? Tôi đã sử dụng gcc 5.3.1 và tôi bị lỗi 'kích thước của biến' arr 'quá lớn' –

Trả lời

8

Loại std::array là:

template< 
    class T, 
    std::size_t N 
> struct array; 

Khi bạn khởi tạo tham số mẫu thứ hai với -1, nó được ngầm chuyển đổi sang một giá trị rất lớn như std::size_tunsigned (đó là bất hợp pháp trong C++ như chỉ bởi other answer và nó nên được chẩn đoán).

Một khả năng khác là arr của bạn được tối ưu hóa. Bạn có thể xác nhận điều này bằng cách thêm -fdump-tree-optimized cờ vào dòng lệnh gcc.

Nếu bạn đảm bảo arr không được tối ưu hóa ra, tôi hy vọng bạn sẽ nhận được following warning:

prog.cpp:5:25: error: size of variable 'arr' is too large 
    std::array<int, -1> arr; 
+1

Không tối ưu hóa có xảy ra sau khi kiểm tra cảnh báo như vậy không? – BartoszKP

+1

@BartoszKP Tôi đã sử dụng 'gcc --std = C++ 11 -O2 -fdump-tree-tối ưu hóa arr_que.cpp' và xác nhận rằng mã được tối ưu hóa chỉ là' return 0; 'như bạn có thể mong đợi. Tôi không chắc liệu có sử dụng sai mục đích thông số mẫu hay không. –

19

Không đó là không hợp pháp. Không có gì về đặc điểm kỹ thuật của std::array ngăn chặn điều này một cách rõ ràng, nhưng nó là bất hợp pháp vì thu hẹp chuyển đổi.

§14.3.2/5:

Đối với một tổ chức phi kiểu mẫu tham số của tích phân hoặc liệt kê loại, chuyển đổi mà cho phép trong một biểu thức hằng chuyển đổi (5,19) được áp dụng.

§5.19/3:

Một chuyển đổi biểu thức hằng số của loại T là một biểu thức hằng đen, ngầm chuyển đổi sang loại T, trong đó việc chuyển đổi ngầm (nếu có) là cho phép trong một biểu thức hằng số theo nghĩa đen và chuỗi chuyển đổi ẩn hiển thị chỉ chứa chuyển đổi do người dùng xác định, chuyển đổi từ giá trị sang giá trị (4.1), quảng cáo không tách rời (4.5) và chuyển đổi không tách rời (4.7) khác với thu hẹp chuyển đổi (8.5.4)

Cách duy nhất để GCC khiếu nại là kích hoạt -Wsign-conversion. Đây là known bug và họ chưa thực hiện bất kỳ chuyển động nào để khắc phục.

Trong Clang bạn nhận được thông báo lỗi dự kiến:

error: non-type template argument evaluates to -1, which cannot be 
narrowed to type 'std::size_t' (aka 'unsigned long') [-Wc++11-narrowing] 
    std::array<int, -1> arr; 
+1

Lưu ý lịch sử: trong C++ 11 đã được xuất bản, nó đã được thực hiện xác định cho dù đây là một chuyển đổi thu hẹp, nhưng điều này đã được cố định bởi DR 1449 để luôn thu hẹp –

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