Search code examples
c++openmp

openMP initialization of the iterator in the for loop with curly braces


I have this main :

int main() {

    std::size_t n{10000};
    std::vector<int> A(n);

    for (size_t k{0}; k < 10000; ++k) { // repeating the same task over and over again.
#pragma omp parallel default(shared)
        {
#pragma omp for    
            for (size_t i = 0; i < n; ++i) {
                A[i] = i;
            }
        }
    }
    return 0;
}

I have the following problem, the initialization with the list initializer (curly braces) does not work :

this works

        for (size_t i = 0; i < n; ++i) {
            A[i] = i;
        }

this doesn't

        for (size_t i{0}; i < n; ++i) {
            A[i] = i;
        }

do you have any idea why ? I have been told one should always initialize with curly braces, instead of = or normal braces ( ).


I use MinGW, on CLion and I fixed my CMake regarding OpenMP as:

FIND_PACKAGE(OpenMP REQUIRED)
if (OPENMP_FOUND)
    set(CMAKE_C_FLAGS "${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()

Solution

  • The OpenMP 5.0 API doesn't allow the following construct:

    #pragma omp for    
        for (size_t i{0}; i < n; ++i) {
            A[i] = i;
        }
    

    Section 2.9.2 says:

    The for directive places restrictions on the structure of all associated for-loops. Specifically, all associated for-loops must have canonical loop form(see Section 2.9.1 on page 95).

    And section 2.9.1 says:

    The loops associated with a loop-associated directive have canonical loop form if they conform to the following:

    ----------------
    for (init-expr;test-expr;incr-expr) structured-block
    ----------------
    init-expr One of the following:
              var=lb
              integer-type var=lb
              random-access-iterator-type var=lb
              pointer-type var=lb
    

    There is no grammar rule that applies to size_t i{0}, and so the code is not conforming. Range-for loops also have canonical form, but that doesn't apply here.