- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using recent (2026, 2025, & 2024) oneAPI C++ on Windows I found that OpenMP parallel for on iterator-based and range-based for loops isn't working in debug builds, but index-based loops work. For example, this demo:
#include <vector>
#include <iostream>
int
main()
{
std::vector< int > v = {0,1,2,3,4,5,6,7,8,9};
// Works
// #pragma omp parallel for
// for ( std::vector< int >::size_type i = 0; i < v.size(); ++i ) {
// ++v[i];
// }
// Fails in in debug build at runtime
#pragma omp parallel for
for ( std::vector< int >::iterator i = v.begin(); i < v.end(); ++i ) {
++(*i);
}
for ( int i : v ) std::cout << i << std::endl;
}compiled with:
icx /nologo /Qopenmp /Qopenmp-simd- /EHsc /Wall /Od /MDd
builds but terminates at runtime, sometimes popping up a dialog with "ITERATOR LIST CORRUPTED". With /MD or /MT it runs fine.
It doesn't appear to be a VC++ standard library limitation because I see the same problem with my own classes, yet I believe this usage worked some years ago.
Maybe this is a known/documented limitation but I couldn't find any information on it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for reporting this issue and providing clear reproduction steps. I can confirm this is a known limitation when using OpenMP with MSVC debug builds (`/MDd`, `/MTd`), not a compiler bug. The issue stems from an incompatibility between:
1. MSVC debug iterators: In debug builds, MSVC's STL iterators contain additional metadata for container ownership tracking, bounds checking, and iterator validation (~24-32 bytes vs. 8 bytes in release)
2. OpenMP privatization: When OpenMP privatizes the loop variable `i` across threads, it performs a bitwise copy but doesn't update the iterator's internal debug metadata
3. Race condition: Multiple threads end up with private iterators that share the same debug metadata structures, leading to concurrent modification and corruption
This manifests as:
- "ITERATOR LIST CORRUPTED" dialog
- Segmentation faults
- Crashes only in debug builds (`/MDd`, `/MTd`)
You may have noticed this warning:
warning: using /MTd or /MDd with '#pragma omp simd' may lead to unexpected fails due to the debugging version of iterators [-Wdebug-option-simd]
While this mentions `#pragma omp simd` specifically, the issue affects all OpenMP constructs that privatize iterators, including `#pragma omp parallel for`. We will work on enhancing this warning message to be more comprehensive and also document this as a known issue.
This limitation exists with any compiler that properly uses MSVC's debug runtime. You mentioned this works with `clang++ -fopenmp`. That's true, but it's not because clang++ handles the issue better it's because:
1. Clang++ on Windows has difficulty linking with MSVC's debug runtime(`/MDd`)
2. When you compile with `clang++ -fopenmp` (even with `-g`), it typically uses the release version of MSVC STL
3. Without debug iterators enabled (`_ITERATOR_DEBUG_LEVEL=2`), there's no metadata to corrupt
4. You can verify this: try `clang++ -fopenmp -D_DEBUG -D_ITERATOR_DEBUG_LEVEL=2` and you'll get linking errors
You may temporarily disable iterator debugging by adding #define _ITERATOR_DEBUG_LEVEL 0 before any STL includes or compile with /D_ITERATOR_DEBUG_LEVEL=0 but this will disable all iterator safety checks in your debug build, which may hide other iterator-related bugs. The recommended practice would be to use index-based loops with OpenMP on Windows.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Additional information...
Using oneAPI 2026.1 on Linux (Ubuntu 2026.04), the iterator-based and range-based loops work in debug builds with OpenMP enabled, such as when compiled with:
icpx -fiopenmp -Wall -O0 -debug
And using Clang bundled with oneAPI, the iterator-based and range-based loops also work on Windows when compiled with:
clang++ -fopenmp -Wall -O0 -g
So the issue appears to be limited to the Intel C++ OpenMP support on Windows.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for reporting this issue and providing clear reproduction steps. I can confirm this is a known limitation when using OpenMP with MSVC debug builds (`/MDd`, `/MTd`), not a compiler bug. The issue stems from an incompatibility between:
1. MSVC debug iterators: In debug builds, MSVC's STL iterators contain additional metadata for container ownership tracking, bounds checking, and iterator validation (~24-32 bytes vs. 8 bytes in release)
2. OpenMP privatization: When OpenMP privatizes the loop variable `i` across threads, it performs a bitwise copy but doesn't update the iterator's internal debug metadata
3. Race condition: Multiple threads end up with private iterators that share the same debug metadata structures, leading to concurrent modification and corruption
This manifests as:
- "ITERATOR LIST CORRUPTED" dialog
- Segmentation faults
- Crashes only in debug builds (`/MDd`, `/MTd`)
You may have noticed this warning:
warning: using /MTd or /MDd with '#pragma omp simd' may lead to unexpected fails due to the debugging version of iterators [-Wdebug-option-simd]
While this mentions `#pragma omp simd` specifically, the issue affects all OpenMP constructs that privatize iterators, including `#pragma omp parallel for`. We will work on enhancing this warning message to be more comprehensive and also document this as a known issue.
This limitation exists with any compiler that properly uses MSVC's debug runtime. You mentioned this works with `clang++ -fopenmp`. That's true, but it's not because clang++ handles the issue better it's because:
1. Clang++ on Windows has difficulty linking with MSVC's debug runtime(`/MDd`)
2. When you compile with `clang++ -fopenmp` (even with `-g`), it typically uses the release version of MSVC STL
3. Without debug iterators enabled (`_ITERATOR_DEBUG_LEVEL=2`), there's no metadata to corrupt
4. You can verify this: try `clang++ -fopenmp -D_DEBUG -D_ITERATOR_DEBUG_LEVEL=2` and you'll get linking errors
You may temporarily disable iterator debugging by adding #define _ITERATOR_DEBUG_LEVEL 0 before any STL includes or compile with /D_ITERATOR_DEBUG_LEVEL=0 but this will disable all iterator safety checks in your debug build, which may hide other iterator-related bugs. The recommended practice would be to use index-based loops with OpenMP on Windows.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks @Sravani_K_Intel . This is sort of what I expected.
Note that I used /Qopenmp-simd- to suppress that simd warning and then it gives no warnings. I appreciate that the warnings (and documentation?) on this will be improved.
For my purposes, the "hardened" standard library you get with /MDd or /MTd are more important in debug builds that enabling OpenMP so I'll just drop /Qopenmp from my normal debug builds. But I can see that it could be useful for some projects to add an OpenMP debug build type that enables OpenMP but uses /MD or /MT.
I wonder if this will become a wider issue as options to use a "hardened" version of other C++ standard libraries are released. The Clang++ hardening modes do not alter the ABI of the library but the full GCC debug mode does.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page