https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95901
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- For OpenMP, we have the C: A stand-alone directive may not be used in place of a substatement in a selection statement, in place of the loop body in an iteration statement, or in place of the statement that follows a label. and C++: A stand-alone directive may not be used in place of a substatement in a selection statement or iteration statement, or in place of the statement that follows a label. restrictions (5.1 wording) and in 5.1+ also similar restriction about declarative directives instead of stand-alone. So, #pragma omp barrier etc. aren't allowed in that spot. The rationale is to avoid different parsing between ignoring the pragmas and when honoring them, case 4: } is invalid, or in if (cond) foo (); foo () is the if then body, but if stand-alone pragmas would be allowed there, case 4: #pragma omp barrier } would be valid and if (cond) #pragma omp barrier foo (); would have foo (); parsed as unconditional after the if. Now, the above mentioned restrictions don't make much sense for the attribute syntax, I'll try to make them specific to pragma syntax. And, while for most of the declarative directives the restrictions make sense for pragma syntax (e.g. declare reduction, declare target, declare mapper), for declare simd and declare variant they actually need a following declaration and C++ allows if (cond) extern int foo (); while C doesn't and so in theory if (cond) #pragma omp declare simd extern int foo (); could be allowed in C++ and not allowed in C. What exactly OpenACC says, I don't know.