Intel® oneAPI DPC++/C++ Compiler
Talk to fellow users of Intel® oneAPI DPC++/C++ Compiler and companion tools like Intel® oneAPI DPC++ Library, Intel® DPC++ Compatibility Tool, and Intel® Distribution for GDB*
879 Discussions

OpenMP fails on iterator and range based loops in Windows debug builds

Mentzer__Stuart
New Contributor I
189 Views

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.

0 Kudos
1 Solution
Sravani_K_Intel
Moderator
121 Views

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. 

View solution in original post

0 Kudos
3 Replies
Mentzer__Stuart
New Contributor I
137 Views

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.

0 Kudos
Sravani_K_Intel
Moderator
122 Views

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. 

0 Kudos
Mentzer__Stuart
New Contributor I
115 Views

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.

0 Kudos
Reply