Udostępnij za pośrednictwem


Checked Iterators

Checked iterators ensure that the bounds of your container are not overwritten.

Checked iterators apply to release builds and debug builds. See Debug Iterator Support for more information about how to use iterators when you compile in debug mode.

Remarks

For information about how to disable warnings that are generated by checked iterators, see _SCL_SECURE_NO_WARNINGS.

You can use the following symbols with the checked iterators feature.

  • _SECURE_SCL
    If defined as 1, unsafe use of iterators causes a runtime error. If defined as 0, checked iterators are disabled. The exact behavior of the runtime error depends on the value of _SECURE_SCL_THROWS. By default, the value for _SECURE_SCL is 0 for release builds and 1 for debug builds. In other words, by default, checked iterators are enabled for debug builds only.

  • _SECURE_SCL_THROWS
    If defined as 1, the use of an out-of-range iterator causes an exception at run time. If the iterator is defined as 0, the program is terminated by calling invalid_parameter. The default value for _SECURE_SCL_THROWS is 0; this means that the program will be terminated by default. Requires that _SECURE_SCL is also defined.

When _SECURE_SCL=1 is defined:

  • All standard iterators (vector::iterator, for example) are checked.

  • The checked form of an algorithm will be used, for standard functions that have checked forms (see the list later in this document).

  • If an output iterator is a checked iterator:

    • You will get checked behavior on calls to the standard function (std::copy, for example).

    • You will get checked behavior on calls to a checked function (stdext::checked_copy, for example).

    • You will get checked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).

  • If the output iterator is an unchecked iterator (an array, for example):

    • Calls to the standard function (std::copy, for example) will cause compiler warnings.

    • Calls to the checked function (stdext::checked_copy, for example) will cause compiler warnings.

    • You will get unchecked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).

  • The following functions will generate a runtime error if there is an access that is outside the bounds of the container:

    basic_string::operator[]

    bitset::operator[]

    deque::back

    deque::front

    deque::operator[]

    list::back

    list::front

    queue::back

    queue::front

    valarray::operator[]

    vector::back

    vector::front

    vector::operator[]

     

     

     

When _SECURE_SCL=0 is defined:

  • All standard iterators are unchecked (iterators can move beyond the container boundaries, which leads to undefined behavior).

  • The unchecked form of a function will be used, for standard functions that have checked forms (see the list later in this document).

  • If an output iterator is a checked iterator:

    • You will get checked behavior on calls to the standard function (std::copy, for example).

    • You will get checked behavior on calls to a checked function (stdext::checked_copy, for example).

    • You will get checked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).

  • If an output iterator is an unchecked iterator:

    • You will get unchecked behavior on calls to the standard function (std::copy, for example).

    • Calls to a checked function (stdext::checked_copy, for example) will cause compiler warnings.

    • You will get unchecked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).

A checked iterator refers to an iterator that will throw an exception or call invalid_parameter if you attempt to move past the boundaries of the container. For more information about invalid_parameter, see Parameter Validation.

A checked algorithm enforces the use of a checked destination iterator. If it is passed an unchecked destination iterator, a checked algorithm will compile, but with warnings. See _SCL_SECURE_NO_WARNINGS for information about how to disable these warnings.

There are two iterator adaptors that support checked iterators:

The following algorithms enforce the use of a checked iterator as output iterator. This is useful when you want to compile by using _SECURE_SCL=0, and when you identify some code where you want to enforce the use of checked iterators. The following algorithms are defined in the stdext namespace.

Note

The following algorithms are Microsoft extensions to the Standard C++ Library. Code that is implemented by using these algorithms is not portable.

checked_adjacent_difference

checked_copy

checked_copy_backward

checked_fill_n

checked_generate_n

checked_merge

checked_partial_sum

checked_remove_copy

checked_remove_copy_if

checked_replace_copy

checked_replace_copy_if

checked_reverse_copy

checked_rotate_copy

checked_set_difference

checked_set_intersection

checked_set_symmetric_difference

checked_set_union

checked_uninitialized_copy

checked_uninitialized_fill_n

checked_unique_copy

 

The following algorithms enable the use of an unchecked iterator as output iterator. This is useful when you want to compile by using _SECURE_SCL=1, and when you want to selectively enable the use of unchecked iterators. The following algorithms are defined in the stdext namespace.

Note

The following algorithms are Microsoft extensions to the Standard C++ Library. Code that is implemented by using these algorithms is not portable.

unchecked_adjacent_difference

unchecked_copy

unchecked_copy_backward

unchecked_fill_n

unchecked_generate_n

unchecked_merge

unchecked_partial_sum

unchecked_remove_copy

unchecked_remove_copy_if

unchecked_replace_copy

unchecked_replace_copy_if

unchecked_reverse_copy

unchecked_rotate_copy

unchecked_set_difference

unchecked_set_intersection

unchecked_set_symmetric_difference

unchecked_set_union

unchecked_uninitialized_copy

unchecked_uninitialized_fill_n

unchecked_unique_copy

 

Example

When you compile by using _SECURE_SCL 1, a runtime error will occur if you attempt to access an element that is outside the bounds of the container by using the indexing operator of certain classes (see earlier in this document).

// checked_iterators_1.cpp
// compile with: /EHsc
#define _SECURE_SCL 1
#define _SECURE_SCL_THROWS 1
#include <vector>
#include <iostream>
using namespace std;
int main() {
   vector<int> v;
   v.push_back(67);
   int i = v[0];
   cout << i << endl;

   try {
      i = v[1];
   }
   catch (std::out_of_range) {
      cout << "invalid container access" << endl;
   }
};
67
invalid container access

When you compile by using _SECURE_SCL 1, a runtime error will occur if you attempt to access an element by using front or back of certain classes (see earlier in this document), when the container is empty.

// checked_iterators_2.cpp
// compile with: /EHsc
#define _SECURE_SCL 1
#define _SECURE_SCL_THROWS 1

#include <vector>
#include <iostream>

int main() {
   using namespace std;   
   vector <int> v1;
   try {
      int& i = v1.front();
   }
   catch (std::out_of_range) {
      cout << "vector is empty!!" << endl;
   }
}
vector is empty!!

When you compile by using _SECURE_SCL 1, the compiler enforces the use of a checked iterator on standard algorithms that also have checked and unchecked versions (see earlier in this document).

// checked_iterators_3.cpp
// compile with: /EHsc /W3
#define _SECURE_SCL 1
#include <algorithm>
#include <iostream>
using namespace std;
using namespace stdext;
int main() {
    int a[] = { 1, 2, 3 };
    int *b = new int[10];
    int c[10];

    copy(a, a + 3, b);   // C4996 unchecked iterator
    copy(a, a + 3, checked_array_iterator<int*>(c, _countof(c)));  // OK

    delete[] b;
}

The following example sets _SECURE_SCL to 0, and thereby disables checked iterators. With checked iterators disabled, you must take extra caution to ensure that you do not iterate beyond the bounds of your container.

// checked_iterators_4.cpp
// compile with: /EHsc
#define _SECURE_SCL 0
#include <vector>
#include <iostream>
using namespace std;
int main() {
   vector<int> v;
   v.push_back(67);
   int i = v[0];
   cout << i << endl;
};
67

See Also

Reference

Standard C++ Library Overview

Debug Iterator Support

Change History

Date

History

Reason

March 2012

Added value description enhancement for _SECURE_SCL.

Content bug fix.