Error static assertion failed comparison object must be invocable as const

Когда я пытаюсь запустить следующий код, и clang (6.0), и g ++ (8) с -std = c ++ 17 выдают ошибку static_assert: #include struct A {}; struct...

Когда я пытаюсь запустить следующий код, и clang (6.0), и g ++ (8) с -std = c ++ 17 выдают ошибку static_assert:

#include <set>
struct A {};

struct ProcessComparator { inline bool operator()(const A&, const A&) { return true; } };

int main(void)
{
std::set<A, ProcessComparator> A_Set;

return EXIT_SUCCESS;
}

г ++ 8

/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_tree.h:457:7: ошибка: Сбой static_assert из-за требования is_invocable_v «объект сравнения должен быть вызван как const»

лязг 6.0

/usr/include/c++/8/bits/stl_tree.h:457:21: ошибка: статическое утверждение не удалось: объект сравнения должен быть вызван как const

Помещение const в качестве части подписи operator () устраняет эту проблему:

#include <set>

struct A {};

/* Add const as part of the operator's signature */
struct ProcessComparator { inline bool operator()(const A&, const A&) const { return true; } };

int main(void)
{
std::set<A, ProcessComparator> A_Set;

return EXIT_SUCCESS;
}

Между тем при std = c ++ 14 ошибка исчезает как в clang, так и в g ++.

Мой вопрос: что изменилось в c ++ 17 для того, чтобы теперь выдавать ошибку, и почему здесь имеет значение const?

Const только гарантирует, что каждый объект, объявленный внутри класса ProcessComparator, не будет изменен (кроме объектов с изменяемым), так почему это требование?


Это исходный код из исходного кода, где статическое утверждение не выполняется:

#if __cplusplus >= 201103L
static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
"comparison object must be invocable with two arguments of key type");
# if __cplusplus >= 201703L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2542. Missing const requirements for associative containers
static_assert(is_invocable_v<const _Compare&, const _Key&, const _Key&>,
"comparison object must be invocable as const");
# endif // C++17
#endif // C++11

Был добавлен новый static_assert, где объект сравнения был изменен с _Compare&< в const _Compare& а также is_invocable в is_invocable_vХотя это, насколько я могу понять, это просто получить inline и constexpr как видно здесь


я обнаружил этот ссылка, основанная на комментарии исходного кода, но я до сих пор не могу понять Зачем это обязательно.

5

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

The GCC 8 release series differs from previous GCC releases in
a number of ways. Some of these are a result
of bug fixing, and some old behaviors have been intentionally changed
to support new standards, or relaxed in standards-conforming ways to
facilitate compilation or run-time performance.

Some of these changes are user visible and can cause grief when
porting to GCC 8. This document is an effort to identify common issues
and provide solutions. Let us know if you have suggestions for improvements!

C++ language issues

-Wreturn-type is enabled by default

G++ now assumes that control never reaches the end of a non-void function
(i.e. without reaching a return statement). This means that
you should always pay attention to -Wreturn-type warnings,
as they indicate code that can misbehave when optimized.

To tell the compiler that control can never reach the end of a function
(e.g. because all callers enforce its preconditions) you can suppress
-Wreturn-type warnings by adding
__builtin_unreachable:


      char signchar(int i) // precondition: i != 0
      {
        if (i > 0)
          return '+';
        else if (i < 0)
          return '-';
        __builtin_unreachable();
      }
  

Because -Wreturn-type is now enabled by default, G++ will
warn if main is declared with an implicit int
return type (which is non-standard but allowed by GCC). To avoid the
warning simply add a return type to main, which makes the
code more portable anyway.

Stricter rules when using templates

G++ now diagnoses even more cases of ill-formed templates which can never
be instantiated (in addition to
the stricter
rules in GCC 7).
The following example will now be diagnosed by G++ because the type of
B<T>::a does not depend on T and so the
function B<T>::f is ill-formed for every possible
instantiation of the template:


      class A { };
      template <typename T> struct B {
        bool f() const { return a; }
        A a;
      };
  
In member function 'bool B<T>::f() const':
error: cannot convert 'const A' to 'bool' in return
   bool f() const { return a; }
                           ^

Ill-formed template code that has never been tested and can never be
instantiated should be fixed or removed.

Changes to alignof results

The alignof operator has been changed to return the minimum
alignment required by the target ABI, instead of the preferred alignment
(consistent with _Alignof in C).

Previously the following assertions could fail on 32-bit x86 but will now
pass. GCC’s preferred alignment for standalone variables of type
double or long long is 8 bytes, but the minimum
alignment required by the ABI (and so used for non-static data members)
is 4 bytes:


      struct D { double val; };
      static_assert(alignof(D) == alignof(double), "...");
      struct L { long long val; };
      static_assert(alignof(L) == alignof(long long), "...");
  

Code which uses alignof to obtain the preferred
alignment can use __alignof__ instead.

Associative containers check the comparison function

The associative containers (std::map,
std::multimap, std::set, and
std::multiset) now use static assertions to check that their
comparison functions support the necessary operations.
In C++17 mode this includes enforcing that the function can be called
when const-qualified:


      struct Cmp {
        bool operator()(int l, int r) /* not const */ { return l < r; }
      };
      std::set<int, Cmp> s;
  
In member function 'bool B<T>::f() const':
error: static assertion failed: comparison object must be invocable as const
       static_assert(is_invocable_v<const _Compare&, const _Key&, const _Key&>,
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   bool f() const { return a; }
                           ^

This can be fixed by adding const to the call operator:


      struct Cmp {
        bool operator()(int l, int r) const { return l < r; }
      };
  

Fortran language issues

The library ABI version has been increased, necessitating a
recompilation of all Fortran code.

Character lengths are now handled as
an INTEGER(kind=C_SIZE_T) variable whose size is
dependent on the target system, allowing characters longer than
2**31 on 64-bit targets. Prior to GCC 8, the character length was
an INTEGER(kind=4) variable on all targets. If calling
a Fortran procedure with character arguments from C (or vice versa)
without using the standard ISO_C_BINDING feature, the hidden
character length argument at the end of the argument list must thus
be modified to be of type size_t rather than of
type int. For instance, calling the Fortran subroutine


      subroutine foo (s, a)
      character(len=*) :: s
      integer :: a
      ! Code here
      end subroutine foo
  

from C in a way that is compatible with older GFortran versions can
be done by defining the prototype as follows:


      #if __GNUC__ > 7
      typedef size_t fortran_charlen_t;
      #else
      typedef int fortran_charlen_t;
      #endif

      void foo_ (char*, int*, fortran_charlen_t);
  

Versions of gfortran prior to 8.1 wrongly accepted CHARACTER
variables with a length type parameter other than one as C
interoperable. For example, the code


  module mod
    use iso_c_binding
    type, bind(C) :: a
      character(len=2,kind=c_char) :: b ! Wrong
    end type a
    character(len=2), bind(C) :: c ! Also wrong
  end module mod
  

was accepted. To achieve similar functionality, an array of
LEN=1 characters can be used, for example


  module mod
    use iso_c_binding
    type, bind(C) :: a
      character(kind=c_char) :: b(2)
    end type a
    character(kind=c_char), bind(C) :: c(2)
  end module mod
  
Skip to content



Open


Issue created Feb 27, 2022 by Sebastian Ehlert@awvwgk

Failure in GCC 11 STL when building CFS dependency for CC4S

Trying to build CC4S with GCC 11 apparently doesn’t work:

❯ mpicxx --showme
g++ -pthread -L/usr/lib/openmpi -Wl,-rpath -Wl,/usr/lib/openmpi -Wl,--enable-new-dtags -lmpi_cxx -lmpi
❯ mpicxx --showme:version
mpicxx: Open MPI 4.1.2 (Language: C++)
❯ mpicxx --version
g++ (GCC) 11.1.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

It fails when compiling CTF with

mpicxx -O3 -fopenmp -Wall  -D_POSIX_C_SOURCE=200112L -D__STDC_LIMIT_MACROS -DFTN_UNDERSCORE=1 -DUSE_LAPACK -DUSE_SCALAPACK   -c idx_tensor.cxx -o /home/awvwgk/projects/src/git/cc4s/extern/build/dist/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/obj/idx_tensor.o
In file included from /usr/include/c++/11.1.0/map:60,
                 from /usr/include/openmpi/ompi/mpi/cxx/mpicxx.h:42,
                 from /usr/include/mpi.h:2887,
                 from ../shared/model.h:7,
                 from common.h:18,
                 from idx_tensor.cxx:3:
/usr/include/c++/11.1.0/bits/stl_tree.h: In instantiation of ‘static const _Key& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_S_key(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type) [with _Key = CTF::Idx_Tensor*; _Val = CTF::Idx_Tensor*; _KeyOfValue = std::_Identity<CTF::Idx_Tensor*>; _Compare = CTF_int::tensor_name_less; _Alloc = std::allocator<CTF::Idx_Tensor*>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<CTF::Idx_Tensor*>*]’:
/usr/include/c++/11.1.0/bits/stl_tree.h:2069:47:   required from ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = CTF::Idx_Tensor*; _Val = CTF::Idx_Tensor*; _KeyOfValue = std::_Identity<CTF::Idx_Tensor*>; _Compare = CTF_int::tensor_name_less; _Alloc = std::allocator<CTF::Idx_Tensor*>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = CTF::Idx_Tensor*]’
/usr/include/c++/11.1.0/bits/stl_tree.h:2122:4:   required from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = CTF::Idx_Tensor*; _Key = CTF::Idx_Tensor*; _Val = CTF::Idx_Tensor*; _KeyOfValue = std::_Identity<CTF::Idx_Tensor*>; _Compare = CTF_int::tensor_name_less; _Alloc = std::allocator<CTF::Idx_Tensor*>]’
/usr/include/c++/11.1.0/bits/stl_set.h:521:25:   required from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = CTF::Idx_Tensor*; _Compare = CTF_int::tensor_name_less; _Alloc = std::allocator<CTF::Idx_Tensor*>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree<CTF::Idx_Tensor*, CTF::Idx_Tensor*, std::_Identity<CTF::Idx_Tensor*>, CTF_int::tensor_name_less, std::allocator<CTF::Idx_Tensor*> >::const_iterator; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other = std::allocator<CTF::Idx_Tensor*>; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key> = __gnu_cxx::__alloc_traits<std::allocator<CTF::Idx_Tensor*>, CTF::Idx_Tensor*>::rebind<CTF::Idx_Tensor*>; typename _Alloc::value_type = CTF::Idx_Tensor*; std::set<_Key, _Compare, _Alloc>::value_type = CTF::Idx_Tensor*]’
idx_tensor.cxx:346:23:   required from here
/usr/include/c++/11.1.0/bits/stl_tree.h:770:15: error: static assertion failed: comparison object must be invocable as const
  770 |               is_invocable_v<const _Compare&, const _Key&, const _Key&>,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/11.1.0/bits/stl_tree.h:770:15: note: ‘std::is_invocable_v<const CTF_int::tensor_name_less&, CTF::Idx_Tensor* const&, CTF::Idx_Tensor* const&>’ evaluates to false
make[5]: *** [Makefile:12: /home/awvwgk/projects/src/git/cc4s/extern/build/dist/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/obj/idx_tensor.o] Error 1
make[5]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/src/interface'
make[4]: *** [Makefile:10: interface] Error 2
make[4]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/src'
make[3]: *** [Makefile:93: ctf_objs] Error 2
make[3]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776'
make[2]: *** [Makefile:238: /home/awvwgk/projects/src/git/cc4s/extern/build/dist/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/lib/libctf.a] Error 2
make[2]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776'
make[1]: *** [Makefile:4: all] Error 2
make[1]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/build/dist/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776'
make: *** [etc/make/ctf.mk:18: /home/awvwgk/projects/src/git/cc4s/extern/build/dist/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/lib/libctf.a] Error 2

Same for Intel 2021.0.5 (uses GCC 11 STL, so no big surprise)

❯ mpiicc -v
mpiicc for the Intel(R) MPI Library 2021.5 for Linux*
Copyright Intel Corporation.
icc version 2021.5.0 (gcc version 11.1.0 compatibility)
❯ mpiicc -show
icc -I"/opt/intel/oneapi/mpi/2021.5.1/include" -L"/opt/intel/oneapi/mpi/2021.5.1/lib/release" -L"/opt/intel/oneapi/mpi/2021.5.1/lib" -Xlinker --enable-new-dtags -Xlinker -rpath -Xlinker "/opt/intel/oneapi/mpi/2021.5.1/lib/release" -Xlinker -rpath -Xlinker "/opt/intel/oneapi/mpi/2021.5.1/lib" -lmpifort -lmpi -ldl -lrt -lpthread

Also fails in a static assert:

mpiicc -O3 -fopenmp -Wall  -D_POSIX_C_SOURCE=200112L -D__STDC_LIMIT_MACROS -DFTN_UNDERSCORE=1 -DUSE_BATCH_GEMM -DUSE_LAPACK -DUSE_MKL   -c world.cxx -o /home/awvwgk/projects/src/git/cc4s/extern/build/icc-mkl-impi/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/obj/world.o
mpiicc -O3 -fopenmp -Wall  -D_POSIX_C_SOURCE=200112L -D__STDC_LIMIT_MACROS -DFTN_UNDERSCORE=1 -DUSE_BATCH_GEMM -DUSE_LAPACK -DUSE_MKL   -c idx_tensor.cxx -o /home/awvwgk/projects/src/git/cc4s/extern/build/icc-mkl-impi/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/obj/idx_tensor.o
/usr/include/c++/11.1.0/bits/stl_tree.h(769): error: static assertion failed with "comparison object must be invocable as const"
  	  static_assert(
  	  ^
          detected during:
            instantiation of "const _Key &std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_S_key(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type) [with _Key=CTF::Idx_Tensor *, _Val=CTF::Idx_Tensor *, _KeyOfValue=std::_Identity<CTF::Idx_Tensor *>, _Compare=CTF_int::tensor_name_less, _Alloc=std::allocator<CTF::Idx_Tensor *>]" at line 2069
            instantiation of "std::pair<std::_Rb_tree_node_base *, std::_Rb_tree_node_base *> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type &) [with _Key=CTF::Idx_Tensor *, _Val=CTF::Idx_Tensor *, _KeyOfValue=std::_Identity<CTF::Idx_Tensor *>, _Compare=CTF_int::tensor_name_less, _Alloc=std::allocator<CTF::Idx_Tensor *>]" at line 2122
            instantiation of "std::pair<std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg &&) [with _Key=CTF::Idx_Tensor *, _Val=CTF::Idx_Tensor *, _KeyOfValue=std::_Identity<CTF::Idx_Tensor *>, _Compare=CTF_int::tensor_name_less, _Alloc=std::allocator<CTF::Idx_Tensor *>, _Arg=CTF::Idx_Tensor *]" at line 521 of "/usr/include/c++/11.1.0/bits/stl_set.h"
            instantiation of "std::pair<std::set<_Key, _Compare, _Alloc>::iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type &&) [with _Key=CTF::Idx_Tensor *, _Compare=CTF_int::tensor_name_less, _Alloc=std::allocator<CTF::Idx_Tensor *>]" at line 346 of "idx_tensor.cxx"

compilation aborted for idx_tensor.cxx (code 2)
make[5]: *** [Makefile:12: /home/awvwgk/projects/src/git/cc4s/extern/build/icc-mkl-impi/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/obj/idx_tensor.o] Error 2
make[5]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/src/interface'
make[4]: *** [Makefile:10: interface] Error 2
make[4]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/src'
make[3]: *** [Makefile:93: ctf_objs] Error 2
make[3]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776'
make[2]: *** [Makefile:238: /home/awvwgk/projects/src/git/cc4s/extern/build/icc-mkl-impi/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/lib/libctf.a] Error 2
make[2]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/src/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776'
make[1]: *** [Makefile:4: all] Error 2
make[1]: Leaving directory '/home/awvwgk/projects/src/git/cc4s/extern/build/icc-mkl-impi/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776'
make: *** [etc/make/ctf.mk:18: /home/awvwgk/projects/src/git/cc4s/extern/build/icc-mkl-impi/ctf/f1d951de96c3f2fc5e76df2b0f6f6148e5216776/lib/libctf.a] Error 2

Bug 786495
media-libs/exempi-2.4.5-r1 — /…/stl_tree.h: error: static assertion failed: comparison object must be invocable as const

Summary:

media-libs/exempi-2.4.5-r1 — /…/stl_tree.h: error: static assertion failed:…

Status: RESOLVED
FIXED

Alias:

None

Product:

Gentoo Linux

Classification:

Unclassified

Component:

Current packages

(show other bugs)

Hardware:

All
Linux

Importance:

Normal
normal
(vote)

Assignee:

Freedesktop bugs

URL:


Whiteboard:

Keywords:

Depends on:


Blocks:



gcc-11
  Show dependency tree

Reported: 2021-04-28 15:53 UTC by Toralf Förster
Modified: 2021-04-29 17:38 UTC
(History)

CC List:

0
users

See Also:

Package list:

Runtime testing required:


Attachments

emerge-info.txt


(emerge-info.txt,17.85 KB,
text/plain)

2021-04-28 15:53 UTC,

Toralf Förster

Details

emerge-history.txt


(emerge-history.txt,385.22 KB,
text/plain)

2021-04-28 15:53 UTC,

Toralf Förster

Details

environment


(environment,69.09 KB,
text/plain)

2021-04-28 15:53 UTC,

Toralf Förster

Details

etc.portage.tar.bz2


(etc.portage.tar.bz2,29.12 KB,
application/x-bzip)

2021-04-28 15:53 UTC,

Toralf Förster

Details

logs.tar.bz2


(logs.tar.bz2,9.31 KB,
application/x-bzip)

2021-04-28 15:53 UTC,

Toralf Förster

Details

media-libs:exempi-2.4.5-r1:20210428-152754.log


(media-libs:exempi-2.4.5-r1:20210428-152754.log,563.25 KB,
text/plain)

2021-04-28 15:53 UTC,

Toralf Förster

Details

temp.tar.bz2


(temp.tar.bz2,38.54 KB,
application/x-bzip)

2021-04-28 15:53 UTC,

Toralf Förster

Details

View All

Add an attachment
(proposed patch, testcase, etc.)

Note
You need to
log in
before you can comment on or make changes to this bug.


Понравилась статья? Поделить с друзьями:
  • Error statement has no effect
  • Error stray 363 in program
  • Error statement cannot resolve address of overloaded function
  • Error stray 361 in program
  • Error state фильтр калмана