De acordo com a especificação OpenMP (2.1. Formato de Diretiva)
Diretivas não podem aparecer em funções constexpr ou em expressões constantes. Pacotes de parâmetros variádicos não podem ser expandidos para uma diretiva ou suas cláusulas, exceto como parte de um argumento de expressão a ser avaliado pela linguagem base, como em uma chamada de função dentro de uma cláusula if.
Eu uso bastante o OpenMP em funções constexpr até que o g++14.2 sem compilador emitiu um aviso. Mas usar o g++15 é um erro.
O seguinte não é um erro do g++14.2, mas sim um erro do g++15.
erro: diretivas OpenMP podem não aparecer em funções 'constexpr' [-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);
}
Qual é o motivo dessa restrição? O compilador tem a capacidade de executar código compatível com OpenMP sem habilitar o OpenMP. Esqueci de alguma coisa?
Estou tentando corrigir meu código com a seguinte solução alternativa. O g++15 não proíbe isso, mas não sei se ele quebra novamente o padrão OpenMP e, por exemplo, no g++16, preciso corrigir meu código novamente.
O seguinte é aceito pela especificação OpenMP? É aceito pelo g++15 (e anteriores).
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();
}