【发布时间】:2017-09-11 06:03:11
【问题描述】:
所以,今天我正在编写一些单元测试,突然 G++ 给了我一个关于 GNU C 和我的一个名为 major 的成员函数的意外警告。为什么我不能有一个名为major 的成员函数而不触发G++?
这是一个最低限度可行的测试 sn-p:
// Any of these includes trigger the warnings
#include <random>
#include <cstdlib>
class my_class {
public:
void major() const;
};
inline void my_class::major() const {}
int main(void) {
my_class my_obj;
my_obj.major();
return 0;
}
这是编译的输出(使用g++ --std=c++14 -o test-gcc-major test-gcc-major.cpp):
[flisboac@sonic ~]$ uname -a && lsb_release -a && g++ -v && g++ --std=c++14 -o test-gcc-major test-gcc-major.cpp && ./test-gcc-major
Linux sonic 4.12.10-1-ARCH #1 SMP PREEMPT Wed Aug 30 12:18:42 CEST 2017 x86_64 GNU/Linux
LSB Version: 1.4
Distributor ID: Arch
Description: Arch Linux
Release: rolling
Codename: n/a
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/7.1.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc-multilib/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp
Thread model: posix
gcc version 7.1.1 20170630 (GCC)
test-gcc-major.cpp:7:13: warning: In the GNU C Library, "major" is defined
by <sys/sysmacros.h>. For historical compatibility, it is
currently defined by <sys/types.h> as well, but we plan to
remove this soon. To use "major", include <sys/sysmacros.h>
directly. If you did not intend to use a system-defined macro
"major", you should undefine it after including <sys/types.h>.
void major() const;
^~~~~~~~
test-gcc-major.cpp:10:13: warning: In the GNU C Library, "major" is defined
by <sys/sysmacros.h>. For historical compatibility, it is
currently defined by <sys/types.h> as well, but we plan to
remove this soon. To use "major", include <sys/sysmacros.h>
directly. If you did not intend to use a system-defined macro
"major", you should undefine it after including <sys/types.h>.
inline void my_class::major() const {}
^~~~~~~~~~~~~~~~~~~~~~~~~~
test-gcc-major.cpp:14:13: warning: In the GNU C Library, "major" is defined
by <sys/sysmacros.h>. For historical compatibility, it is
currently defined by <sys/types.h> as well, but we plan to
remove this soon. To use "major", include <sys/sysmacros.h>
directly. If you did not intend to use a system-defined macro
"major", you should undefine it after including <sys/types.h>.
my_obj.major();
以任何方式引用成员函数的每一行都会触发警告。另外,我不能取消定义任何东西,因为我正在实现一个库,而这个负担应该由最终用户承担。
那么,有人知道为什么会提出这个警告吗?我什至没有在我的代码中的任何地方使用 C。我使用的是<random>,它本身不是C(但可能包含一个“C”库,谁知道呢?)。
无论如何,有没有办法在编译时检测到需要并取消定义major(例如,使用一些预处理器巫术)?
更新:我使用的是<random>,而不是<cstdlib>。我刚刚发现<cstdlib>也触发了警告。
【问题讨论】:
-
错误是不言自明的,我会说。这是
sys/sysmacros.h中的一个宏。你很幸运,GCC 会警告你,而不是仅仅编译代码并让你对即将发生的奇怪事情摸不着头脑。 -
错误信息用非常好的英语解释了问题。您也不应该在新的 C++ 代码中使用
random。 -
@n.m 我正在使用
。请仔细阅读帖子。 -
@StoryTeller 问题是是否有任何方法可以在编译时检查这一点,而不是取消定义其他编译器中未定义的内容。是否有一系列我应该关注的版本?
-
“函数被重命名”是的,这就是问题所在。您的 glibc 太旧并且不包含弃用警告,它只是默默地破坏了代码。
标签: c++ g++ libc gcc-warning libstdc++