Dela via


Checked Iterators

Checked iterators ensure that you do not overwrite the bounds of your container.

Checked iterators apply to release builds and debug builds. See Debug Iterator Support for more information on using iterators when compiling in debug mode.

Remarks

For information on how to disable warnings generated by checked iterators, see _SCL_SECURE_NO_WARNINGS.

The following symbols are for use with the checked iterators feature.

  • _SECURE_SCL
    If defined as 1, unsafe iterator use 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. The default value for _SECURE_SCL is 1, meaning checked iterators are enabled by default.

  • _SECURE_SCL_THROWS
    If defined as 1, an out of range iterator use causes an exception at runtime. If defined as 0, the program is terminated by calling invalid_parameter. The default value for _SECURE_SCL_THROWS is 0, meaning the program will be terminated by default. Requires _SECURE_SCL to also be 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 with checked forms (see list below).

  • 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 result in compiler warnings.

    • Calls to the checked function (stdext::checked_copy, for example) will result in 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 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, leading to undefined behavior).

  • The unchecked form of a function will be used, for standard functions with checked forms (see list below).

  • 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 result in 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 passed an unchecked destination iterator, a checked algorithm will compile, but with warnings. See _SCL_SECURE_NO_WARNINGS for information on 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 with _SECURE_SCL=0, and where you identify some code where you want to enforce the use of checked iterators. The following algorithms are all defined in the stdext namespace.

Note

The following algorithms are Microsoft extensions to the Standard C++ Library. Code implemented using these algorithms will not be 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 allow the use of an unchecked iterator as output iterator. This is useful when you want to compile with _SECURE_SCL=1, and where you want to selectively allow the use of unchecked iterators. The following algorithms are all defined in the stdext namespace.

Note

The following algorithms are Microsoft extensions to the Standard C++ Library. Code implemented using these algorithms will not be 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 compiling with _SECURE_SCL 1, a runtime error will occur if you attempt to access an element outside the bounds of the container with the indexing operator of certain classes (see above).

// 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 compiling with _SECURE_SCL 1, a runtime error will occur if you attempt to access an element with front or back of certain classes (see above), 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 compiling with _SECURE_SCL 1, the compiler enforces the use of a checked iterator on standard algorithms that also have checked and unchecked versions (see above).

// 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, thus disabling checked iterators. With checked iterators disabled, you must take extra caution to ensure 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