Manu343726/ctti

error: body of constexpr function ‘ctti::pretty_function::type()' not a return-statement

Opened this issue · 3 comments

Hi,

using gcc-4.8.5 I get the following error:

g++ -std=c++11 -I../include main.cpp -omain
In file included from ../include/ctti/nameof.hpp:4:0,
                 from main.cpp:1:
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = int]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int]’
../include/ctti/type_id.hpp:120:38:   required from ‘constexpr ctti::type_id_t ctti::detail::type_id() [with T = int]’
../include/ctti/type_id.hpp:147:35:   required from ‘constexpr ctti::type_id_t ctti::type_id() [with T = int]’
main.cpp:24:38:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = char]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = char]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = char]’
../include/ctti/type_id.hpp:120:38:   required from ‘constexpr ctti::type_id_t ctti::detail::type_id() [with T = char]’
../include/ctti/type_id.hpp:147:35:   required from ‘constexpr ctti::type_id_t ctti::type_id() [with T = char]’
main.cpp:24:63:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = char]’ not a return-statement
main.cpp: In function ‘int main()’:
main.cpp:24:5: error: non-constant condition for static assertion
     static_assert(ctti::type_id<int>() != ctti::type_id<char>(), "what?");
     ^
In file included from main.cpp:1:0:
main.cpp:24:38:   in constexpr expansion of ‘ctti::type_id<int>()’
../include/ctti/type_id.hpp:147:35:   in constexpr expansion of ‘ctti::detail::type_id<int>()’
../include/ctti/type_id.hpp:120:38:   in constexpr expansion of ‘ctti::nameof<int>()’
../include/ctti/nameof.hpp:51:48:   in constexpr expansion of ‘ctti::detail::nameof_impl<T>::apply<int>()’
../include/ctti/nameof.hpp:30:47: error: ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int]’ called in a constant expression
         return ctti::pretty_function::type<T>().pad(
                                               ^
In file included from ../include/ctti/nameof.hpp:4:0,
                 from main.cpp:1:
../include/ctti/detail/pretty_function.hpp:27:33: note: ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int]’ is not usable as a constexpr function because:
 constexpr ctti::detail::cstring type()
                                 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::value() [with T = int foo::*; T Value = &foo::i]’:
../include/ctti/nameof.hpp:16:51:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int foo::*; T Value = &foo::i]’
../include/ctti/nameof.hpp:42:39:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<ctti::detail::static_value<T, Value> >::apply() [with T = int foo::*; T Value = &foo::i]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = ctti::detail::static_value<int foo::*, &foo::i>]’
main.cpp:27:59:   required from here
../include/ctti/detail/pretty_function.hpp:36:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::value() [with T = int foo::*; T Value = &foo::i]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int foo::*]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = int foo::*]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int foo::*]’
../include/ctti/nameof.hpp:17:53:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int foo::*; T Value = &foo::i]’
../include/ctti/nameof.hpp:42:39:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<ctti::detail::static_value<T, Value> >::apply() [with T = int foo::*; T Value = &foo::i]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = ctti::detail::static_value<int foo::*, &foo::i>]’
main.cpp:27:59:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int foo::*]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::value() [with T = int (*)(const std::basic_string<char>&, int); T Value = f]’:
../include/ctti/nameof.hpp:16:51:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int (*)(const std::basic_string<char>&, int); T Value = f]’
../include/ctti/nameof.hpp:42:39:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<ctti::detail::static_value<T, Value> >::apply() [with T = int (*)(const std::basic_string<char>&, int); T Value = f]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = ctti::detail::static_value<int (*)(const std::basic_string<char>&, int), f>]’
main.cpp:28:54:   required from here
../include/ctti/detail/pretty_function.hpp:36:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::value() [with T = int (*)(const std::basic_string<char>&, int); T Value = f]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int (*)(const std::basic_string<char>&, int)]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = int (*)(const std::basic_string<char>&, int)]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int (*)(const std::basic_string<char>&, int)]’
../include/ctti/nameof.hpp:17:53:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = int (*)(const std::basic_string<char>&, int); T Value = f]’
../include/ctti/nameof.hpp:42:39:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<ctti::detail::static_value<T, Value> >::apply() [with T = int (*)(const std::basic_string<char>&, int); T Value = f]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = ctti::detail::static_value<int (*)(const std::basic_string<char>&, int), f>]’
main.cpp:28:54:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = int (*)(const std::basic_string<char>&, int)]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::value() [with T = bar_enum; T Value = (bar_enum)0]’:
../include/ctti/nameof.hpp:16:51:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = bar_enum; T Value = (bar_enum)0]’
../include/ctti/nameof.hpp:42:39:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<ctti::detail::static_value<T, Value> >::apply() [with T = bar_enum; T Value = (bar_enum)0]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = ctti::detail::static_value<bar_enum, (bar_enum)0>]’
main.cpp:29:65:   required from here
../include/ctti/detail/pretty_function.hpp:36:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::value() [with T = bar_enum; T Value = (bar_enum)0]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = bar_enum]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = bar_enum]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = bar_enum]’
../include/ctti/nameof.hpp:17:53:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = bar_enum; T Value = (bar_enum)0]’
../include/ctti/nameof.hpp:42:39:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<ctti::detail::static_value<T, Value> >::apply() [with T = bar_enum; T Value = (bar_enum)0]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = ctti::detail::static_value<bar_enum, (bar_enum)0>]’
main.cpp:29:65:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = bar_enum]’ not a return-statement
 }
 ^
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = std::basic_ostream<char>]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = std::basic_ostream<char>]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = std::basic_ostream<char>]’
../include/ctti/type_id.hpp:120:38:   required from ‘constexpr ctti::type_id_t ctti::detail::type_id() [with T = std::basic_ostream<char>]’
../include/ctti/type_id.hpp:138:62:   required from ‘constexpr ctti::type_id_t ctti::type_id(T&&) [with T = std::basic_ostream<char>&]’
main.cpp:30:41:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = std::basic_ostream<char>]’ not a return-statement
../include/ctti/detail/pretty_function.hpp: In instantiation of ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = std::basic_istream<char>]’:
../include/ctti/nameof.hpp:30:47:   required from ‘static constexpr ctti::detail::cstring ctti::detail::nameof_impl<T>::apply() [with T = std::basic_istream<char>]’
../include/ctti/nameof.hpp:51:48:   required from ‘constexpr ctti::detail::cstring ctti::nameof() [with T = std::basic_istream<char>]’
../include/ctti/type_id.hpp:126:51:   required from ‘constexpr ctti::unnamed_type_id_t ctti::detail::unnamed_type_id() [with T = std::basic_istream<char>]’
../include/ctti/type_id.hpp:158:70:   required from ‘constexpr ctti::unnamed_type_id_t ctti::unnamed_type_id(T&&) [with T = std::basic_istream<char>&]’
main.cpp:31:48:   required from here
../include/ctti/detail/pretty_function.hpp:30:1: error: body of constexpr function ‘constexpr ctti::detail::cstring ctti::pretty_function::type() [with T = std::basic_istream<char>]’ not a return-statement

but when using gcc-7.2 I get the another error:

g++-7 -std=c++11 -I../include main.cpp -omain
main.cpp: In function ‘int main()’:
main.cpp:24:5: error: non-constant condition for static assertion
     static_assert(ctti::type_id<int>() != ctti::type_id<char>(), "what?");
     ^~~~~~~~~~~~~
main.cpp:24:40:   in constexpr expansion of ‘ctti::operator!=(ctti::type_id<int>(), ctti::type_id<char>())’
../include/ctti/type_id.hpp:52:26:   in constexpr expansion of ‘ctti::operator==(lhs, rhs)’
../include/ctti/type_id.hpp:47:28:   in constexpr expansion of ‘(& lhs)->ctti::type_id_t::hash()’
../include/ctti/type_id.hpp:37:30:   in constexpr expansion of ‘((const ctti::type_id_t*)this)->ctti::type_id_t::name_.ctti::detail::cstring::hash()’
../include/ctti/detail/cstring.hpp:48:24:   in constexpr expansion of ‘ctti::detail::sid_hash(((const ctti::detail::cstring*)this)->ctti::detail::cstring::length(), ((const ctti::detail::cstring*)this)->ctti::detail::cstring::begin(), 14695981039346656037)’
main.cpp:24:5: error: the value of ‘__PRETTY_FUNCTION__’ is not usable in a constant expression
In file included from ../include/ctti/nameof.hpp:4:0,
                 from main.cpp:1:
../include/ctti/detail/pretty_function.hpp:13:34: note: ‘__PRETTY_FUNCTION__’ was not declared ‘constexpr’
     #define CTTI_PRETTY_FUNCTION __PRETTY_FUNCTION__
                                  ^
../include/ctti/detail/pretty_function.hpp:29:13: note: in expansion of macro ‘CTTI_PRETTY_FUNCTION’
     return {CTTI_PRETTY_FUNCTION};
             ^~~~~~~~~~~~~~~~~~~~

This happens because the compiler (or its STL, I'm not 100% user about who exactly "defines" __PRETTY_FUNCTION__) does not define __PRETTY_FUNCTION__ as constexpr. Unfortunately, ctti will not work in that case, See https://github.com/Manu343726/ctti#support-and-current-status and https://github.com/Manu343726/ctti#conditional-features.

What I don't understand is why it doesn't work for you since you're using gcc 7 and the GCC docs explicitly state that __PRETTY_FUNCTION__ is defined as constexpr if C++11 is enabled (and the compiler supports it). My ci build is running with GCC 5.x iirc, and at home I work with GCC 7 and its working for me, I experimented with different GCCs and I've found that 4.x does not define constexpr __PRETTY_FUNCTION__ but 5.x and upwards seem to do so as the docs state.

I also had a problem with __PRETTY_FUNCTION__ in gcc 7.2.0 with --std=c++17 and optimizations flags major than 0 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66639). My (brute force) solution was to include ctti headers between pragmas of optimization -O0:

#pragma GCC push_options
#pragma GCC optimize ("O0")
#include <ctti/type_id.hpp>
#pragma GCC pop_options

Hope it can help someone.
If you find a better solution please tell me.

GCC-9.0 doesn't allow __PRETTY_FUNCTION__ in constexpr.
error: the value of '__PRETTY_FUNCTION__' is not usable in a constant expression
CLANG-8.0 allows but results are unexpected garbage.
GCC-8.2 allows and it works as expected. So it looks like 8.2 is the last compiler that handles constexpr __PRETTY_FUNCTION__ .