According to OpenMP specification (2.1. Directive Format)
Directives may not appear in constexpr functions or in constant expressions. Variadic parameter packs cannot be expanded into a directive or its clauses except as part of an expression argument to be evaluated by the base language, such as into a function call inside an if clause.
I extensively use OpenMP in constexpr functions until g++14.2 without compiler made a warning. But using g++15 is an error.
The following is not a g++14.2 error but it is a g++15 error.
error: OpenMP directives may not appear in 'constexpr' functions [-Wtemplate-body]
constexpr void func(size_t sz) noexcept
{
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (size_t i = 0; i < sz; ++i) something(i);
}
Which is the reason for this restriction? Compiler has the ability to execute OpenMP-aware code without enabling OpenMP. Did I miss something?
I am trying to patch my code with the following workaround. g++15 does not forbid this but I don't know if it breaks again the OpenMP standard and in e.g. g++16 I must again patch my code.
Is the following accepted from OpenMP specification? It is accepted from g++15 (and previous).
constexpr void func(size_t sz) noexcept
{
auto fcommon = [](size_t i) {};
auto fomp = [sz]()
{
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (size_t i = 0; i < sz; ++i) fcommon(i);
};
auto fseq = [sz]() { for (size_t i = 0; i < sz; ++i) fcommon(i); };
if (std::is_constant_evaluated()) fseq(); else fomp();
}
constexprwithoutOpenMPand one non-constexpr with openmp. Then you are in line with the openmp specs (and I expect the code to be even a bit more readable)