Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile failed with error "error: macro "__has_attribute" requires an identifier" #1693

Closed
hthao opened this issue Feb 15, 2022 · 14 comments · Fixed by #1783
Closed

compile failed with error "error: macro "__has_attribute" requires an identifier" #1693

hthao opened this issue Feb 15, 2022 · 14 comments · Fixed by #1783

Comments

@hthao
Copy link

hthao commented Feb 15, 2022

Describe the bug (描述bug)
compile failed with error "error: macro "__has_attribute" requires an identifier".

To Reproduce (复现方法)
follow the steps:
https://github.com/apache/incubator-brpc/blob/master/docs/cn/getting_started.md#ubuntulinuxmintwsl

Expected behavior (期望行为)
compile successful.

Versions (各种版本)
OS: ubuntu 21.10
Compiler: gcc 11.2.0
brpc: 1.0.0
protobuf: libprotoc 3.12.4

Additional context/screenshots (更多上下文/截图)
test@NUC11PAHi7:~/github/brpc$ cd incubator-brpc-1.0.0/
test@NUC11PAHi7:~/github/brpc/incubator-brpc-1.0.0$ sh config_brpc.sh --headers=/usr/include --libs=/usr/lib
test@NUC11PAHi7:~/github/brpc/incubator-brpc-1.0.0$ make

Compiling src/mcpack2pb/generator.o
g++ -c -I./src -I/usr/include/ -DBRPC_WITH_GLOG=0 -DGFLAGS_NS=google -g -DBTHREAD_USE_FAST_PTHREAD_MUTEX -D__const__= -D_GNU_SOURCE -DUSE_SYMBOLIZE -DNO_TCMALLOC -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -DBRPC_REVISION="1.0.0" -O2 -pipe -Wall -W -fPIC -fstrict-aliasing -Wno-invalid-offsetof -Wno-unused-parameter -fno-omit-frame-pointer -std=c++0x -msse4 -msse4.2 -Wno-aligned-new src/mcpack2pb/generator.cpp -o src/mcpack2pb/generator.o
In file included from /usr/include/features.h:484,
from /usr/include/x86_64-linux-gnu/c++/11/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/11/bits/c++config.h:586,
from /usr/include/c++/11/bits/stl_algobase.h:59,
from /usr/include/c++/11/bits/stl_tree.h:63,
from /usr/include/c++/11/set:60,
from src/mcpack2pb/generator.cpp:22:
/usr/include/x86_64-linux-gnu/sys/cdefs.h:256:60: error: macro "__has_attribute" requires an identifier
256 | #if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__)
| ^
make: *** [Makefile:297: src/mcpack2pb/generator.o] Error 1

test@NUC11PAHi7:~/github/brpc/incubator-brpc-1.0.0$ uname -a

Linux NUC11PAHi7 5.13.0-28-generic #31-Ubuntu SMP Thu Jan 13 17:41:06 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

test@NUC11PAHi7:~/github/brpc/incubator-brpc-1.0.0$ gcc --version

gcc (Ubuntu 11.2.0-7ubuntu2) 11.2.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.

test@NUC11PAHi7:~/github/brpc/incubator-brpc-1.0.0$ cat /etc/issue

Ubuntu 21.10 \n \l

@TousakaRin
Copy link
Contributor

谢谢反馈,该问题是因为在编译时指定了选项 -D__const__= 导致的,brpc在编译时需要添加这个宏来避免gcc对errno宏做优化从而导致未定义行为

你的系统文件(/usr/include/x86_64-linux-gnu/sys/cdefs.h) 在 #if 中测试了 __glibc_has_attribute (__const__),这个宏展开之后是 __has_attribute (__const__), 由于brpc在编译时将 const 定义成了空,所以报错了。比较快的解决方案是直接删掉后边的 __glibc_has_attribute (__const__)

ps:提issue的时候可以预览一下,编译错误里的__const__变成了加粗的 const

@hthao
Copy link
Author

hthao commented Feb 15, 2022

谢谢反馈,该问题是因为在编译时指定了选项 -D__const__= 导致的,brpc在编译时需要添加这个宏来避免gcc对errno宏做优化从而导致未定义行为

你的系统文件(/usr/include/x86_64-linux-gnu/sys/cdefs.h) 在 #if 中测试了 __glibc_has_attribute (__const__),这个宏展开之后是 __has_attribute (__const__), 由于brpc在编译时将 const 定义成了空,所以报错了。比较快的解决方案是直接删掉后边的 __glibc_has_attribute (__const__)

ps:提issue的时候可以预览一下,编译错误里的__const__变成了加粗的 const

谢谢快速反馈,issue格式已修正。
修改系统文件貌似不现实,可能还需要再研究一下解决方案,多谢。

@wwbmmm
Copy link
Contributor

wwbmmm commented Mar 18, 2022

类似的问题,用gcc 12.0.1中,使用了c++11风格的attribute,编译失败
image

@LilyWangLL
Copy link

Does this issue has new update?

@wwbmmm
Copy link
Contributor

wwbmmm commented Apr 7, 2022

有一个trick的方法,可以把-D__const__= 改成 -D__const__=__unused__
找了半天似乎就这个unused的attribute影响最小:
60f18635e94211fdb3f3c1ef3e1a7b43

@LilyWangLL
Copy link

有一个trick的方法,可以把-D__const__= 改成 -D__const__=__unused__ 找了半天似乎就这个unused的attribute影响最小: 60f18635e94211fdb3f3c1ef3e1a7b43

Thanks for your reply, Does this fix will be merged to codes of brpc? If this fix merged, I will add a patch on vcpkg.

@zouyonghao
Copy link

有一个trick的方法,可以把-D__const__= 改成 -D__const__=__unused__ 找了半天似乎就这个unused的attribute影响最小: 60f18635e94211fdb3f3c1ef3e1a7b43

Thanks!

@songdongsheng
Copy link

在使用 brpc 的代码中,全面关闭 const 优化是极为不负责任的做法,这么粗暴的绕过问题,会让人对 brpc 的代码质量产生疑虑,阻碍 brpc 的推广。

  1. 如果 brpc 认为 glibc 做得不对,可以给它报告 bug,说明理由。
  2. 作为一个临时方案,定义一个 bthread_errno() 或 brpc_errno(),比简单粗暴的禁止 const 优化优雅,也易于让人接受。

@wwbmmm
Copy link
Contributor

wwbmmm commented May 26, 2022

2. 作为一个临时方案,定义一个 bthread_errno() 或 brpc_errno(),比简单粗暴的禁止 const 优化优雅,也易于让人接受。

这个方案在 https://github.com/apache/incubator-brpc/blob/master/src/bthread/errno.h 已经实现了。问题在于,不只是brpc自身代码在使用errno时需要include "bthread/errno.h", 用户代码里也要加,包括用户通过第三方库间接使用到errno的情况。除了errno,还有pthread_self等函数也需要处理,这样搞很容易疏漏,导致未定义的行为,而且难以追查。

给glibc报bug的方案,我再看看

@wwbmmm
Copy link
Contributor

wwbmmm commented Jun 1, 2022

给glibc报bug的方案,我再看看

查了一些资料。目前找到的比较充分的讨论是LLVM社区的这个讨论:[llvm-dev] [RFC] Coroutine and pthread_self
相关Issue:llvm/llvm-project#47177

讨论中提到的一些问题:

  1. gcc关于函数的const attribute的说明,并没有写清楚是否是在 同一线程下 执行结果相同,在实践中,却被广泛地当成 同一线程下 执行结果相同来处理。比如基础库中存在大量将返回tls变量地址的函数定义为const的情况,而编译器也默认只在同一个函数调用内将多次const函数调用进行合并。有人在gcc社区要求澄清,但是没有得到明确的答复。
  2. 上述实践在过去没有问题,因为在同一个函数中的代码总是在同一个线程中执行。但是协程的出现打破了这种情况(无论是c++20的协程还是类似bthread的这种协程),同一个函数中的代码可能会被协程切换到另一个线程下执行。

讨论的几种解决方案:

  1. 修改pthread_self()等函数的声明。但是,这个问题在于要改很多基础库。
  2. 编译器识别当前函数是否存在协程环境(如co_await关键字),如果存在,则放弃某些优化。这个需要修改很多个优化器,并且会给将来新增的优化器带来负担。并且如何判断协程环境也是个困难(bthread调用并没有co_await这样的标志)。
  3. 新增一个编译器开关来指定是否支持协程安全,如果开启这个开关,则对tls变量和const函数进行特殊处理以确保在协程环境下运行正确。实际上,MSVC已经提供了这样的开关。个人认为这个方案是比较理想的方案。

目前,LLVM社区有一些PR在尝试解决这个问题:

其它相关讨论:

@baiwfg2
Copy link

baiwfg2 commented Jun 6, 2022

有一个trick的方法,可以把-D__const__= 改成 -D__const__=__unused__ 找了半天似乎就这个unused的attribute影响最小: 60f18635e94211fdb3f3c1ef3e1a7b43

按照这个做法后,出现

In file included from /data/incubator-brpc/bld/incubator-brpc-1.1.0/src/bthread/errno.h:26,                                                                                          
                 from /data/incubator-brpc/bld/incubator-brpc-1.1.0/src/brpc/log.h:22,                                                                                               
                 from /data/incubator-brpc/bld/incubator-brpc-1.1.0/src/brpc/ts.cpp:37:                                                                                              
/data/incubator-brpc/bld/incubator-brpc-1.1.0/src/butil/errno.h:25: warning: "__const__" redefined

应该没关系吧

@wwbmmm
Copy link
Contributor

wwbmmm commented Jun 7, 2022

有一个trick的方法,可以把-D__const__= 改成 -D__const__=__unused__ 找了半天似乎就这个unused的attribute影响最小: 60f18635e94211fdb3f3c1ef3e1a7b43

按照这个做法后,出现

In file included from /data/incubator-brpc/bld/incubator-brpc-1.1.0/src/bthread/errno.h:26,                                                                                          
                 from /data/incubator-brpc/bld/incubator-brpc-1.1.0/src/brpc/log.h:22,                                                                                               
                 from /data/incubator-brpc/bld/incubator-brpc-1.1.0/src/brpc/ts.cpp:37:                                                                                              
/data/incubator-brpc/bld/incubator-brpc-1.1.0/src/butil/errno.h:25: warning: "__const__" redefined

应该没关系吧

@baiwfg2 试试 #1783 , 已修复warning

@songdongsheng
Copy link

  1. 修改pthread_self()等函数的声明。但是,这个问题在于要改很多基础库。

不是很理解仅仅删除这个编译优化提示__attribute__ ((const))为什么要改其它基础库?

ARM Compiler 的文档说得更清楚,只有函数的返回值只依赖其输入参数时才可以使用__attribute__ ((const))
https://developer.arm.com/documentation/100067/0612/Compiler-specific-Function--Variable--and-Type-Attributes/--attribute----const---function-attribute

@wwbmmm
Copy link
Contributor

wwbmmm commented Jun 9, 2022

不是很理解仅仅删除这个编译优化提示__attribute__ ((const))为什么要改其它基础库?

用到__atrribute((const))的地方很多,不只是glibc,其它库也可能会用到,哪些该删哪些不该删,需要一个一个排查。

ARM Compiler 的文档说得更清楚,只有函数的返回值只依赖其输入参数时才可以使用__attribute__ ((const))https://developer.arm.com/documentation/100067/0612/Compiler-specific-Function--Variable--and-Type-Attributes/--attribute----const---function-attribute

这个描述确实比gcc的文档清楚些,但估计看这个文档的人不多。。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants