C++ G++;不';t允许我定义名为";的成员函数;“主要”;

C++ G++;不';t允许我定义名为";的成员函数;“主要”;,c++,g++,libc,gcc-warning,libstdc++,C++,G++,Libc,Gcc Warning,Libstdc++,所以,今天我正在编写一些单元测试,突然G++给了我一个关于gnuc和我的一个名为major的成员函数的意外警告。为什么我不能有一个名为major的成员函数而不触发G++ 这是一个最小可行的测试片段: // Any of these includes trigger the warnings #include <random> #include <cstdlib> class my_class { public: void major() const; }; i

所以,今天我正在编写一些单元测试,突然G++给了我一个关于gnuc和我的一个名为
major
的成员函数的意外警告。为什么我不能有一个名为
major
的成员函数而不触发G++

这是一个最小可行的测试片段:

// 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;
}
对于以任何方式引用成员函数的每一行,都会触发警告。另外,我不能取消定义任何内容,因为我正在实现一个库,这个负担应该由最终用户承担

那么,有人知道为什么会提出这个警告吗?我甚至没有在我的代码中使用C。我使用的是
,它本身不是C(但可能包括一个“C”库,谁知道呢?)

在任何情况下,是否有任何方法可以在编译时检测需求并取消定义
major
(例如,使用一些预处理器巫术)


更新:我使用的是
,而不是
。我刚刚发现
也会触发警告。

不幸的是,解决方法是停止尝试使名为
的成员成为主要成员。否则,您将需要
#undef major
,这对于库来说似乎很不愉快(可能是在头文件中)。

取消定义宏是可以的,它在这里只是为了向后兼容,很快就会被删除,并且一开始就不应该在那里。此
#undef
不可能破坏或损坏用户代码


如果用户需要宏和头包含在同一源文件中,请让他们自己进行排序。无论如何,他们都必须这样做,不管你是否包含一个有问题的标题,不管你是否
#undef
它。

我想说,这个错误是不言自明的。它是sys/sysmacros.h
中的一个宏。幸运的是,GCC警告您,而不仅仅是编译代码,让您对将要发生的奇怪事情刮目相看。错误消息用非常好的英语解释了问题。你也不应该在新的C++代码中使用<代码>随机<代码>。我正在使用。请仔细阅读这篇文章。@StoryTeller问题是是否有任何方法在编译时检查这一点,而不是取消定义未在其他编译器中定义的内容。有一系列的版本我应该关注吗?“函数被重命名为”是的,这就是问题所在。你的glibc太旧了,没有包含弃用警告,它只是默默地破坏了代码。我希望会有一个功能标志或
#define
,可以避免此警告,而不会破坏需要此定义的客户端。也许最好尽可能的非侵入性,因此重命名函数是一种方法。这是非常不幸的,因为就这个函数而言,
major
是我的领域中最好的名字。
[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();