首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LLVM STLExtras中出错:应在GCC11的“const”之前使用未限定的id

LLVM STLExtras中出错:应在GCC11的“const”之前使用未限定的id
EN

Stack Overflow用户
提问于 2021-05-26 12:26:41
回答 2查看 219关注 0票数 0

我刚刚将我的编译器升级到了GCC 11.1.0,在尝试编译我的使用LLVM的程序时遇到了问题。

出现的错误如下:

代码语言:javascript
复制
In file included from /usr/include/llvm/IR/DebugInfo.h:19,
                 from /home/<redacted>/src/sword/format/llvm.hpp:12,
                 from /home/<redacted>/src/main.cpp:9:
/usr/include/llvm/ADT/STLExtras.h:1793:18: error: expected unqualified-id before ‘const’
 1793 |   result_pair<R>(const result_pair<R> &Other)
      |                  ^~~~~
/usr/include/llvm/ADT/STLExtras.h:1793:18: error: expected ‘)’ before ‘const’
 1793 |   result_pair<R>(const result_pair<R> &Other)
      |                 ~^~~~~
      |                  )
/usr/include/llvm/ADT/STLExtras.h:1843:22: error: expected unqualified-id before ‘const’
 1843 |   enumerator_iter<R>(const enumerator_iter<R> &Other) : Result(Other.Result) {}
      |                      ^~~~~
/usr/include/llvm/ADT/STLExtras.h:1843:22: error: expected ‘)’ before ‘const’
 1843 |   enumerator_iter<R>(const enumerator_iter<R> &Other) : Result(Other.Result) {}
      |                     ~^~~~~
      |                      )

我已经看过源代码了,但不确定LLVM的代码是格式错误,还是有一个GCC的bug。

STLExtra.h中第1793行的错误与类的定义有关:

代码语言:javascript
复制
template <typename R> struct result_pair {
  ...
  result_pair<R>(const result_pair<R> &Other)
      : Index(Other.Index), Iter(Other.Iter) {}
  ...
};

通常,当我使用模板参数定义一个类时,我不会将模板参数放在构造函数的声明中(即result_pair(...))。实际上,当我将构造函数从result_pair<R>(...)修改为result_pair(...) (对enumerator_iter也是如此)时,我的程序编译得很好。

那么,LLVM的代码是错的,而GCC是正确的吗?还是说这是一种GCC的回归?我对C++标准的了解太有限了,无法有效地在谷歌上检查这是否是一个已知的bug……任何帮助都是非常感谢的。

此外,我尝试使用clang-11编译我的程序,但它根本无法编译,因为C++20功能还不存在(具体地说,它在模板中的某个地方失败了)。所以,我不能这样缩小罪犯的范围。

附注:由于修改后编译得很好,我想我现在只需要修改头文件即可。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-26 12:34:30

你提到你正在使用C++20,这确实是一个错误:对于构造函数使用simple-template-ids被认为是容易出错和多余的,并被删除了。参见[diff.cpp17.class]/2

正如您所提到的,您可以通过使用注入的类名来修复错误:

代码语言:javascript
复制
template <typename R>
struct result_pair {
  // ...
  result_pair(const result_pair &Other)
      : Index(Other.Index), Iter(Other.Iter) {}
  // ...
};

特别是,这可以防止在构造函数声明中意外使用错误的模板参数,这显然是不应该编译的。

票数 5
EN

Stack Overflow用户

发布于 2021-10-21 14:50:09

根据N.Shead的回答,以下是一个补丁文件,可用于修复LLVM 12.0.1上的错误:

代码语言:javascript
复制
--- /usr/include/llvm/ADT/STLExtras.h.orig  2021-10-21 10:41:36.706064183 -0400
+++ /usr/include/llvm/ADT/STLExtras.h   2021-10-21 10:41:59.442775225 -0400
@@ -1820,9 +1820,9 @@
   result_pair(std::size_t Index, IterOfRange<R> Iter)
       : Index(Index), Iter(Iter) {}
 
-  result_pair<R>(const result_pair<R> &Other)
+  result_pair(const result_pair &Other)
       : Index(Other.Index), Iter(Other.Iter) {}
-  result_pair<R> &operator=(const result_pair<R> &Other) {
+  result_pair &operator=(const result_pair &Other) {
     Index = Other.Index;
     Iter = Other.Iter;
     return *this;
@@ -1856,22 +1856,22 @@
   result_type &operator*() { return Result; }
   const result_type &operator*() const { return Result; }
 
-  enumerator_iter<R> &operator++() {
+  enumerator_iter &operator++() {
     assert(Result.Index != std::numeric_limits<size_t>::max());
     ++Result.Iter;
     ++Result.Index;
     return *this;
   }
 
-  bool operator==(const enumerator_iter<R> &RHS) const {
+  bool operator==(const enumerator_iter &RHS) const {
     // Don't compare indices here, only iterators.  It's possible for an end
     // iterator to have different indices depending on whether it was created
     // by calling std::end() versus incrementing a valid iterator.
     return Result.Iter == RHS.Result.Iter;
   }
 
-  enumerator_iter<R>(const enumerator_iter<R> &Other) : Result(Other.Result) {}
-  enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {
+  enumerator_iter(const enumerator_iter &Other) : Result(Other.Result) {}
+  enumerator_iter &operator=(const enumerator_iter &Other) {
     Result = Other.Result;
     return *this;
   }

将上述内容保存到~/STLExtras.h.patch,然后通过以下方式应用补丁:

代码语言:javascript
复制
$ sudo patch --backup /usr/include/llvm/ADT/STLExtras.h ~/STLExtras.h.patch
patching file /usr/include/llvm/ADT/STLExtras.h

原件将被保存到/usr/include/llvm/ADT/STLExtras.h.orig,您可以保留或删除它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67698523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档