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:
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.
Notes
The following algorithms are Microsoft extensions to the Standard C++ Library. Code implemented using these algorithms will not be portable.
|
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.
Notes
The following algorithms are Microsoft extensions to the Standard C++ Library. Code implemented using these algorithms will not be portable.
|
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