如何隐藏#pragma 消息的额外输出

How to hide extra output from #pragma message

现状

gcc bugtracker 中的错误归档(包括简单的测试用例):https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66234


我目前正在将一些代码移植到新平台和工具链,其中包括从 gcc 4.7.2 升级到 gcc 4.9.2(或更具体地说,从 OSELAS toolchains 的 2012 版到 2014 版) - 我还使用 gcc 4.6.4(有效)和 gcc 4.8.3(无效)在我的主机上重现了该行为。

在构建应用程序期间,我使用了一些 #pragma message 语句来输出构建日期和主机名(请注意,BUILDTAGBUILDHOST 也存储为常量以供之后申请):

#define BUILDTAG (__DATE__  " "  __TIME__)
#define BUILDHOST BUILT_ON

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#pragma message "Setting builddate to: " STR(BUILDTAG)
#pragma message "Building on: " STR(BUILDHOST)

旧的工具链(gcc 4.7.2 / 4.6.4)输出如下,这正是我想要的:

note: #pragma message: Setting builddate to: ("May 15 2015" " " 10:35:12")
note: #pragma message: Building on: my-host

然而,新的工具链 (gcc 4.9.2 / 4.8.3) 给我:

note: #pragma message: Setting builddate to: ("May 15 2015" " " "10:39:35")
#pragma message "Setting builddate to: " STR(BUILDTAG)
^
note: in definition of macro 'STR_HELPER'
#define STR_HELPER(x) #x
                       ^
note: in expansion of macro 'STR'
#pragma message "Setting builddate to: " STR(BUILDTAG)
                                         ^
note: #pragma message: Building on: my-host
#pragma message "Building on: " STR(BUILDHOST)
                                             ^
note: in definition of macro 'STR_HELPER'
#define STR_HELPER(x) #x
                       ^
note: in expansion of macro 'STR'
#pragma message "Building on: " STR(BUILDHOST)
                                ^

(请注意,我已从两个清单的输出中删除文件 path/location。)

当然,我想要的输出在那里,但还有很多额外的东西。无论如何隐藏额外的 in definition of macro / in expansion of macro / 等消息,同时保持所需的输出?

或者我只是做错了,有没有更好的方法来打印消息?

简答

要隐藏额外的输出,请传递 GCC 4.8 版中添加的 -ftrack-macro-expansion=0-fno-diagnostics-show-caret 选项。

长答案

这看起来像是 GCC 中的错误,您可能想要报告。它看起来与 this bug.

相同或相关

我发现能够使用 vanilla(从源代码构建)GCC 版本 4.9.2 重现它:

$ cat test.c 
#define BUILDTAG (__DATE__  " "  __TIME__)
#define BUILDHOST BUILT_ON

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#pragma message "Setting builddate to: " STR(BUILDTAG)
#pragma message "Building on: " STR(BUILDHOST)
$ g++ -c test.c
test.c:7:1: note: #pragma message: Setting builddate to: ("May 18 2015" " " "14:36:12")
 #pragma message "Setting builddate to: " STR(BUILDTAG)
 ^
test.c:4:24: note: in definition of macro 'STR_HELPER'
 #define STR_HELPER(x) #x
                        ^
test.c:7:42: note: in expansion of macro 'STR'
 #pragma message "Setting builddate to: " STR(BUILDTAG)
                                          ^
test.c:8:46: note: #pragma message: Building on: BUILT_ON
 #pragma message "Building on: " STR(BUILDHOST)
                                              ^
test.c:4:24: note: in definition of macro 'STR_HELPER'
 #define STR_HELPER(x) #x
                        ^
test.c:8:33: note: in expansion of macro 'STR'
 #pragma message "Building on: " STR(BUILDHOST)
                                 ^

请注意,它只出现在 C++ 预处理器中(即 g++ 而不是 gcc),如果你通过 -ftrack-macro-expansion=0:

就会消失
$ gcc -c test.c
test.c:7:9: note: #pragma message: Setting builddate to: ("May 18 2015" " " "14:36:17")
 #pragma message "Setting builddate to: " STR(BUILDTAG)
         ^
test.c:8:9: note: #pragma message: Building on: BUILT_ON
 #pragma message "Building on: " STR(BUILDHOST)
         ^
$ g++ -c test.c -ftrack-macro-expansion=0
test.c:7:42: note: #pragma message: Setting builddate to: ("May 18 2015" " " "14:36:35")
 #pragma message "Setting builddate to: " STR(BUILDTAG)
                                          ^
test.c:8:33: note: #pragma message: Building on: BUILT_ON
 #pragma message "Building on: " STR(BUILDHOST)
                                 ^

change log for GCC 4.8 中,它显示 -ftrack-macro-expansion=2 现在默认通过,这解释了为什么此行为在版本 4.7.2 中不存在。

如果你想得到与 4.7.2 相同的输出,你也可以传递 -fno-diagnostics-show-caret(这也是在 GCC 4.8 中添加的):

$ g++ -c test.c -ftrack-macro-expansion=0 -fno-diagnostics-show-caret
test.c:7:42: note: #pragma message: Setting builddate to: ("May 18 2015" " " "14:39:48")
test.c:8:33: note: #pragma message: Building on: BUILT_ON

使用 g++ 版本 8.3.1 .

发现将消息放在括号内会减少输出消息的数量。

示例:

#define XSTR(x) STR(x)
#define STR(x) #x
#pragma message "BOOST_VERSION: " XSTR(BOOST_VERSION)

输出为:

<filename>:17:53: note: #pragma message: BOOST_VERSION: 106600
 #pragma message "BOOST_VERSION: " XSTR(BOOST_VERSION)
                                                     ^
<filename>:16:17: note: in definition of macro ‘STR’
 #define STR(x) #x
                 ^
<filename>:17:35: note: in expansion of macro ‘XSTR’
 #pragma message "BOOST_VERSION: " XSTR(BOOST_VERSION)
                                   ^~~~

几乎相同的代码,但括号中的消息为:

#define XSTR(x) STR(x)
#define STR(x) #x
#pragma message ("BOOST_VERSION: " XSTR(BOOST_VERSION))

输出变为:

<filename>:17:55: note: #pragma message: BOOST_VERSION: 106600
 #pragma message ("BOOST_VERSION: " XSTR(BOOST_VERSION))
                                                       ^