2017-09-11 26 views
3

그래서, 지금은 단위 테스트를 코딩하고 있었는데 갑자기 G ++에서 GNU C와 major이라는 멤버 함수 중 하나에 대한 예기치 않은 경고를 받았습니다. G ++을 트리거하지 않고 major이라는 멤버 함수를 사용할 수없는 이유는 무엇입니까?G ++에서는 "major"라는 멤버 함수를 정의 할 수 없습니다.

이 최소한 가능한 테스트 코드 조각입니다 :

// 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 사용) :

[[email protected] ~]$ 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의 정의를 해제 할 수있는 방법이 있습니까?

업데이트 :<cstdlib>이 아닌 <random>을 사용하고 있습니다. 방금 <cstdlib>도 경고를 유발한다는 것을 알았습니다.

+3

오류 자체는 설명 적입니다. 'sys/sysmacros.h'에있는 매크로입니다. GCC는 단지 코드를 컴파일하는 대신에 일어날 이상한 일에 머리를 찰 필요가 있다고 경고합니다. – StoryTeller

+0

오류 메시지는 완벽하게 좋은 영어의 문제를 설명합니다. 새로운 C++ 코드에서'random'을 사용해서는 안됩니다. –

+0

@ n.m 을 사용하고 있습니다. 게시물을 더 자세히 읽으십시오. –

답변

5

이전 버전과의 호환성을 위해서만 여기에있는 매크로를 정의 해제하는 것이 좋으며 곧 제거 될 것이며 처음부터 있었던 것이 아니어야합니다. 이 #undef이 사용자 코드를 손상 시키거나 해칠 수있는 방법은 없습니다.

사용자가 매크로 헤더를 동일한 소스 파일에 포함해야하는 경우 사용자가 직접 정렬 할 수 있도록하십시오. 어쨌든, 당신이 불쾌한 헤더를 포함하든 그렇지 않든간에 당신은 #undef이든 아니든 상관하지 않아야합니다.

1

불행히도 해결책은 major이라는 회원을 만들려고하지 않는 것입니다. 그렇지 않으면 #undef major이 필요합니다. 라이브러리에서 (아마도 헤더 파일에서) 상당히 불쾌한 것처럼 보입니다.

+0

이 정의를 필요로하는 클라이언트를 깨지 않으면 서이 경고를 피할 수있는 기능 플래그 나'#define'이 있기를 바랬습니다. 가능한 한 비 관입 적이기 때문에 기능을 변경하는 것이 더 좋은 방법 일 수 있습니다. 'major'는 그 기능을 위해서 내 도메인에서 가장 좋은 이름이기 때문에 이것은 매우 불행한 일입니다. –