2009-06-12 24 views
16

Việc triển khai xác nhận thời gian biên dịch hiện tại của chúng tôi dựa trên chỉ mục mảng âm và nó cung cấp đầu ra chẩn đoán kém trên GCC. C++ 0x's static_assert là một tính năng rất đẹp, và đầu ra chẩn đoán nó cung cấp tốt hơn nhiều. Tôi biết GCC đã triển khai một số tính năng C++ 0x. Có ai biết nếu static_assert là một trong số họ và nếu nó là sau đó kể từ khi phiên bản GCC?GCC có xác nhận thời gian biên dịch tích hợp không?

+1

http://en.wikichip.org/wiki/c/static_assertions –

Trả lời

29

Theo this page, gcc đã có static_assert kể từ 4.3.

+19

1 cho không sử dụng LMGTFY . – Johnsyweb

8

Các mã sau đây làm việc như mong đợi với g ++ 4.4.0 khi biên soạn với -std=c++0x cờ:

int main() { 
    static_assert(false, "that was false"); 
} 

nó sẽ hiển thị:

x.cpp: In function 'int main()': 
x.cpp:2: error: static assertion failed: "that was false" 
16

Nếu bạn cần phải sử dụng một phiên bản gcc mà không làm hỗ trợ nó, bạn có thể sử dụng

#include <boost/static_assert.hpp> 

BOOST_STATIC_ASSERT(/* assertion */) 

Về cơ bản, tăng cường là gì:

Declare (nhưng không xác định!) Một

template< bool Condition > struct STATIC_ASSERTION_FAILURE; 

Xác định chuyên môn đối với trường hợp mà sự khẳng định nắm giữ:

template <> struct STATIC_ASSERTION_FAILURE<true> {}; 

Sau đó, bạn có thể định nghĩa STATIC_ASSERT như thế này:

#define STATIC_ASSERT(Condition) \ 
    enum { dummy = sizeof(STATIC_ASSERTION_FAILURE< (bool)(Condition) > } 

Bí quyết là nếu Điều kiện là sai trình biên dịch cần phải khởi tạo cấu trúc

STATIC_ASSERTION_FAILURE<false> 

để tính kích thước của nó và điều này không thành công do không được xác định.

+2

Tôi tự hỏi nếu có bất kỳ cách nào để thực hiện một thông báo lỗi hợp lý xuất hiện từ một thủ thuật như thế này ... – Thomas

+0

Theo tài liệu (http://www.boost.org/doc/libs/1_43_0/doc/html/boost_staticassert. html), đây là một trong những mục tiêu của Boost.StaticAssert: “Một trong những mục tiêu của BOOST_STATIC_ASSERT là tạo ra các thông báo lỗi có thể đọc được. Những điều này ngay lập tức cho người dùng biết rằng một thư viện đang được sử dụng theo cách không được hỗ trợ. ” – Philipp

+0

Có một dấu ngoặc đơn bị thiếu trong' ... (Điều kiện)>} ', có thể là' ... (Điều kiện)>)} '. Tôi đã cố chỉnh sửa nhưng bị từ chối ... – mbschenkel

1

Điều này không thực sự trả lời câu hỏi, nhưng tôi thích các xác nhận biên dịch dựa trên trường hợp chuyển đổi tốt hơn, ví dụ:

#define COMPILE_TIME_ASSERT(cond) do { switch(0) { case 0: case cond: ; } } while (0) 

Hoạt động trong C và không chỉ bằng C++.

+4

Kỹ thuật này có hai thiếu sót. Đầu tiên, xác nhận như vậy không thể được sử dụng ở cấp lớp hoặc không gian tên. Và thứ hai, khi xác nhận thành công, nó tạo ra mã thực thi, làm tăng số nhị phân. Nó là trái để trình biên dịch tối ưu hóa của bạn để loại bỏ nó, và đó không phải là đảm bảo. :-( – VladLosev

1

bạn luôn có thể chơi xung quanh với các mẫu và không tồn tại strutures qua mẫu -specialization. Đây là cách tăng cường hiện nó theo như tôi biết. Đây là những gì tôi sử dụng như một static_assert, nó khá thẳng về phía trước.

namespace Internal 
{ 
template<bool x> struct SASSERT_F; 
template<  > struct SASSERT_F <true> {}; 
template<int x> struct SASSERT_P  {}; 
#define STATIC_ASSERT(B)   \ 
    typedef Internal::SASSERT_P <(\ 
    sizeof (Internal::SASSERT_F <(\ 
     ((B)? true : false)) >) \ 
           )> \ 
     StaticAssert##__LINE__ () 
} 

ví dụ về Sử dụng

int main(int argc, char **argv) 
{ 
    static_assert(sizeof(int) == 1)   // Error 
    static_assert(sizeof(int) == sizeof(int)) // OK 
} 
1

NSPR làm:

#define PR_STATIC_ASSERT(condition) \ 
    extern void pr_static_assert(int arg[(condition) ? 1 : -1]) 

mà thất bại nếu condition là sai vì nó tuyên bố một mảng có độ dài tiêu cực.

0

Cả

BOOST_STATIC_ASSERT(x) 
    BOOST_STATIC_ASSERT_MSG(x, msg) 

sẽ sử dụng C++ 11 static_assert nếu trình biên dịch của bạn hỗ trợ nó

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