2009-08-17 18 views
24

Tôi đang sử dụng Visual Studio 2008.Làm thế nào để làm cho std :: operator vector của [] biên dịch làm giới hạn kiểm tra trong DEBUG nhưng không phải trong CHÍ

Tôi biết rằng std :: vector có giới hạn kiểm tra với tại() chức năng và có hành vi không xác định nếu bạn cố gắng truy cập một cái gì đó bằng cách sử dụng toán tử [] không chính xác (ngoài phạm vi).

Tôi rất tò mò nếu có thể biên dịch chương trình của tôi với kiểm tra giới hạn. Bằng cách này, toán tử [] sẽ sử dụng hàm at() và ném một std :: out_of_range bất cứ khi nào một cái gì đó nằm ngoài giới hạn.

Chế độ phát hành sẽ được biên dịch mà không có giới hạn kiểm tra cho toán tử [], do đó hiệu suất không bị suy giảm.

Tôi đã suy nghĩ về điều này vì tôi đang di chuyển một ứng dụng được viết bằng Borland C++ sang Visual Studio và trong một phần nhỏ của mã tôi có (với i = 0, j = 1):

v[i][j]; //v is a std::vector<std::vector<int> > 

Kích thước của vectơ 'v' là [0] [1] (vì vậy phần tử 0 của vectơ chỉ có một phần tử). Đây là hành vi không xác định, tôi biết, nhưng Borland đang trở về 0 ở đây, VS đang gặp sự cố. Tôi thích vụ tai nạn tốt hơn là trả về 0, vì vậy nếu tôi có thể nhận thêm 'sự cố' bởi std :: out_of_range ngoại lệ bị ném, việc di chuyển sẽ được hoàn thành nhanh hơn (vì vậy nó sẽ tiết lộ nhiều lỗi mà Borland đang ẩn).

Trả lời

28

Visual Studio 2005 và 2008 đã kiểm tra giới hạn theo số operator[] theo mặc định, trong cả hai lỗi phát hành xây dựng.

vĩ mô để kiểm soát hành vi này là _SECURE_SCL. Đặt nó về 0 để vô hiệu hóa vọt kiểm tra.

kế hoạch hiện tại của họ trong VS2010 là để vô hiệu hóa vọt kiểm tra theo mặc định trong phiên bản xây dựng, nhưng giữ nó vào trong gỡ lỗi.(Macro cũng bị đổi tên thành _ITERATOR_DEBUG_LEVEL. Tôi không biết nếu có bất kỳ tài liệu chính thức có sẵn trên đó, nhưng nó đã được đề cập herehere)

+0

+1 Hoàn hảo. Bạn sẽ tìm ra những thứ như tên mới ở đâu? Chỉ cần nhìn vào các tập tin tiêu đề mới? – GManNickG

+0

chỉ được cập nhật với một số thông tin khác – jalf

+0

Cảm ơn bạn! [15char] – GManNickG

-4

C++ định nghĩa toán tử vector [] như không ném ngoại lệ vì lợi ích của tốc độ.

Tôi khuyên bạn nên thử nghiệm ứng dụng trong Cấu hình gỡ lỗi trong một thời gian cho đến khi bạn nhận được sự tự tin rằng các lỗi "ẩn" chính bị mất.

+7

C++ để nó không xác định điều gì xảy ra nếu [] vượt quá giới hạn. Điều đó có nghĩa là nó là hợp pháp cho một thực hiện để thực hiện kiểm tra giới hạn, và một số làm. – jalf

4

Tôi đã hỏi điều này quá sớm, nhưng tôi vẫn đăng câu trả lời để tôi chia sẻ một số kiến ​​thức.

Thực hiện stl trong Visual Studio đã kiểm tra giới hạn khi biên dịch trong chế độ Gỡ lỗi. Bạn có thể thấy điều này tại tiêu đề <vector>:

reference operator[](size_type _Pos) 
     { // subscript mutable sequence 

#if _HAS_ITERATOR_DEBUGGING 
     if (size() <= _Pos) 
      { 
      _DEBUG_ERROR("vector subscript out of range"); 
      _SCL_SECURE_OUT_OF_RANGE; 
      } 
#endif /* _HAS_ITERATOR_DEBUGGING */ 
     _SCL_SECURE_VALIDATE_RANGE(_Pos < size()); 

     return (*(_Myfirst + _Pos)); 
     } 

để kiểm tra giới hạn cho lớp vectơ. Tôi không nhìn vào các thùng chứa khác, nhưng tôi tự tin rằng họ có cùng một cơ chế.

+0

uhuh. Bạn đã quikier hơn tôi trên bài đăng này ;-) –

+0

Tương tự ở đây :) Điều đó nói rằng, tôi * * khá chắc chắn rằng nó tiếp tục làm điều này kiểm tra ngay cả trong Release. Có một macro bạn phải xác định để tắt hoàn toàn. – GManNickG

+0

yep, xem bài đăng của tôi – jalf

0

Tôi hiện không có quyền truy cập vào bất kỳ máy tính cửa sổ nào. Nhưng nếu tôi nhìn vào việc thực hiện STL giao với g ++ trên mac os x máy tính của tôi, từ /usr/include/c++/4.0.0/bits/stl_vector.h:

// element access 
    /** 
    * @brief Subscript access to the data contained in the %vector. 
    * @param n The index of the element for which data should be 
    * accessed. 
    * @return Read/write reference to data. 
    * 
    * This operator allows for easy, array-style, data access. 
    * Note that data access with this operator is unchecked and 
    * out_of_range lookups are not defined. (For checked lookups 
    * see at().) 
    */ 
    reference 
    operator[](size_type __n) 
    { return *(begin() + __n); } 

Không kiểm tra thực hiện, sự kiện mặc dù trong Chế độ kiểm tra sửa lỗi. Không có _GLIBCXX_DEBUG marcro được kiểm tra ở đây trong mã này.

Có giao diện triển khai STL của riêng bạn được cung cấp cùng với MSVC và xem những gì được thực hiện. Nếu không có séc nào được định dạng trong mọi trường hợp ... bạn không có lựa chọn nào khác ngoài việc sử dụng tại() .. :-(

+1

MSVC thực hiện kiểm tra giới hạn theo mặc định (trong VC8 và 9 * cả hai * trong gỡ lỗi và phát hành bản dựng, trong VC10 chỉ trong gỡ lỗi) – jalf

+2

Câu trả lời của bạn không nhìn vào bên trong việc thực hiện tiến trình lặp. –

12

Kích hoạt tính năng _GLIBCXX_DEBUG cờ để làm kiểm tra giới hạn về STL container, như được thảo luận ở đây: http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

+1

Tại sao macro libstdC++ hoạt động trong Visual Studio? Và bạn không có nghĩa là thư viện chuẩn C++? –

+0

Có tương đương với điều này cho libC++ không? – celticminstrel

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