Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

G++ doesn't allow me to define a member function named "major"

So, today I was coding some unit tests, and suddenly G++ gave me an unexpected warning regarding GNU C and one of my member functions named major. Why can't I have a member function named major without triggering G++?

This is a minimally viable test snippet:

// 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;
}

And this is the output of the compilation (using 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();

The warning is triggered for every line referencing the member function in any way. Also, I can't undefine anything, because I'm implementing a library, and that burden should fall under the final user.

So, does someone know why this warning is being raised up? I'm not even using C anywhere in my code. All I'm using is <random>, which is not C, per se (but may include a "C" library, who knows?).

In any case, is there any way to detect the need and undefine major at compile-time (e.g. with some pre-processor voodoo)?

UPDATE: I'm using <random>, not <cstdlib>. I just found out that <cstdlib>also triggers the warning.

like image 530
Flávio Lisbôa Avatar asked Jan 29 '23 15:01

Flávio Lisbôa


1 Answers

It is OK to undefine the macro, which is here for backward compatibility only, will soon be removed, and shouldn't have been there in the first place. There is no way this #undef can possibly break or harm user code.

If your users need the macro and your header included in the same source file, let them sort it out themselves. They would have to anyway, whether you include an offending header or not and whether you #undef it or not.

like image 119
n. 1.8e9-where's-my-share m. Avatar answered Feb 08 '23 15:02

n. 1.8e9-where's-my-share m.