constexpr fails with clang but not with g++

61 views
Skip to first unread message

Florian Lindner

unread,
Jun 25, 2015, 5:18:33 AM6/25/15
to std-dis...@isocpp.org
Hello,

I have this piece of code: (not written by me)


#include "mpi.h"

// template <size_t>
// struct MPI_Select_unsigned_integer_datatype;

// template <>
// struct MPI_Select_unsigned_integer_datatype<1> {
// static constexpr MPI_Datatype const datatype = MPI_UNSIGNED_CHAR;
// };


int main(int argc, char *argv[])
{
constexpr MPI_Datatype const datatype = MPI_UNSIGNED_CHAR;
return 0;
}


The actual code is the commented out, but the constexpr line produces the
same error.

It compiles fine with g++ 5.1 but fails with clang++ 3.6.1:


% OMPI_CXX="clang++" mpic++ -std=c++11 test.cpp
test.cpp:14:32: error: constexpr variable 'datatype' must be initialized by
a constant expression
constexpr MPI_Datatype const datatype = MPI_UNSIGNED_CHAR;
^ ~~~~~~~~~~~~~~~~~
test.cpp:14:43: note: cast from 'void *' is not allowed in a constant
expression
constexpr MPI_Datatype const datatype = MPI_UNSIGNED_CHAR;
^
/usr/include/mpi.h:1049:27: note: expanded from macro 'MPI_UNSIGNED_CHAR'
#define MPI_UNSIGNED_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype,
ompi_mpi_unsigned_char)
^
/usr/include/mpi.h:308:47: note: expanded from macro
'OMPI_PREDEFINED_GLOBAL'
#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) ((void *) &(global)))
^
1 error generated.


First question: Is the const statement superfluous?

I don't understand why clang fires the error here. MPI_UNSIGNED_CHAR is just
a #define in mpi.h

#define MPI_UNSIGNED_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype,
ompi_mpi_unsigned_char)

which is

#if !OMPI_BUILDING
#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) ((void *) &(global)))
#else
#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
#endif


And a bit beyond my understanding of C and C++.

What is the best way to fix compilation with clang?

Is that the same problem?
http://stackoverflow.com/questions/24398102/constexpr-and-initialization-of-a-static-const-void-pointer-with-reinterpret-cas

Thanks!

Florian


Jens Maurer

unread,
Jun 25, 2015, 5:45:57 AM6/25/15
to std-dis...@isocpp.org
Yes. "constexpr" implies "const" for variables:

7.1.5p9
"A constexpr specifier used in an object declaration declares the object as const."

> I don't understand why clang fires the error here. MPI_UNSIGNED_CHAR is just
> a #define in mpi.h
>
> #define MPI_UNSIGNED_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype,
> ompi_mpi_unsigned_char)
>
> which is
>
> #if !OMPI_BUILDING
> #define OMPI_PREDEFINED_GLOBAL(type, global) ((type) ((void *) &(global)))
> #else
> #define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
> #endif

5.20p2.11:

"-- a conversion from type cv void * to a pointer-to-object type;"

(This is intended to prevent type punning in constant expressions.)

> And a bit beyond my understanding of C and C++.
>
> What is the best way to fix compilation with clang?

Don't use constexpr in that case. It's very unlikely you need it here.
No, that's 5.20p2.13.

Jens

Faisal Vali

unread,
Jun 25, 2015, 5:52:57 AM6/25/15
to std-dis...@isocpp.org
I don't think MPI_Datatype is a pointer - i believe this falls afoul
of 5.20p2.13 too.


>
>> And a bit beyond my understanding of C and C++.
>>
>> What is the best way to fix compilation with clang?
>
> Don't use constexpr in that case. It's very unlikely you need it here.
>
>> Is that the same problem?
>> http://stackoverflow.com/questions/24398102/constexpr-and-initialization-of-a-static-const-void-pointer-with-reinterpret-cas
>
> No, that's 5.20p2.13.
>
> Jens
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
> To post to this group, send email to std-dis...@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Reply all
Reply to author
Forward
0 new messages