gccで予め定義されたマクロ_GNUC__

12531 ワード

テキストアドレスhttp://www.cnblogs.com/Cccarl/p/7215515.html?utm_source=itdadao&utm_medium=referral
今日はLinuxシステムのプログラミングという本のコードを読んでいたらGNUC__,このマクロがよくわからないので調べて記録しておきます.GNU Cは一連のマクロを事前定義しており、これらのマクロは二重下線で始まり、ここでは_GNUC__  __GNUC_MINOR__ __GNUC_PATCHLEVEL__,他のGNU Cの事前定義マクロはここで見ることができます.
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros
 
__GNUC__ 、__GNUC_MINOR__ 、__GNUC_PATCHLEVEL__それぞれgccのメインバージョン番号、セカンダリバージョン番号、修正バージョン番号を表します.ここでは、上記の公式説明を引用します.__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
These macros are defined by all GNU compilers that use the C preprocessor: C, C++, Objective-C and Fortran. Their values are the major version, minor version, and patch level of the compiler, as integer constants. For example, GCC 3.2.1 will define  __GNUC__  to 3,  __GNUC_MINOR__  to 2, and  __GNUC_PATCHLEVEL__  to 1. These macros are also defined if you invoke the preprocessor directly. __GNUC_PATCHLEVEL__  is new to GCC 3.0; it is also present in the widely-used development snapshots leading up to 3.0 (which identify themselves as GCC 2.96 or 2.97, depending on which snapshot you have).
If all you need to know is whether or not your program is being compiled by GCC, or a non-GCC compiler that claims to accept the GNU C dialects, you can simply test  __GNUC__ . If you need to write code which depends on a specific version, you must be more careful. Each time the minor version is increased, the patch level is reset to zero; each time the major version is increased (which happens rarely), the minor version and patch level are reset. If you wish to use the predefined macros directly in the conditional, you will need to write it like this:
          /* Test for GCC > 3.2.0 */
          #if __GNUC__ > 3 || \
              (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
                                 (__GNUC_MINOR__ == 2 && \
                                  __GNUC_PATCHLEVEL__ > 0))

Another approach is to use the predefined macros to calculate a single number, then compare that against a threshold:
          #define GCC_VERSION (__GNUC__ * 10000 \
                               + __GNUC_MINOR__ * 100 \
                               + __GNUC_PATCHLEVEL__)
          ...
          /* Test for GCC > 3.2.0 */
          #if GCC_VERSION > 30200

Many people find this form easier to understand. 
 
上の大きな英語は実際に話しています.
なお、__GNUC_PATCHLEVEL__はgcc 3.0以降であり、これまでのgccにはこのマクロが予め定義されていなかった.私达はgcc--versionで自分のシステムの中のgccバージョンを见ることができて、今のgccバージョンは普遍的にすべて3.0后でしょう、私のシステムにとって、4.9.2で、それでは対応する__GNUC__ 4,__GNUC_MINOR__ 9,__GNUC_PATCHLEVEL__ 2。 int, , 。 , 。 , , (gcc -E) , :
#include 

int main()
{
#ifdef __GNUC__
    printf("__GNUC__ = %d
",__GNUC__); #endif #ifdef __GNUC_MINOR__ printf("__GNUC_MINOR__ = %d
",__GNUC_MINOR__); #endif #ifdef __GNUC_PATCHLEVEL__ printf("__GNUC_PATCHLEVEL__ = %d
",__GNUC_PATCHLEVEL__); #endif return 0; }


 
プリコンパイル後のファイル関数セクション:
# 942 "/usr/include/stdio.h" 3 4

# 2 "test.c" 2

int main()
{

    printf("__GNUC__ = %d
",4); printf("__GNUC_MINOR__ = %d
",9); printf("__GNUC_PATCHLEVEL__ = %d
",2); return 0; }


これで直感的に見ることができます__GNUC__ 4,__GNUC_MINOR__ 9,__GNUC_PATCHLEVEL__ 2。なぜこの3つのマクロを事前定義したのですか?これは、特定のバージョンのgccコンパイラに対してコードの作成を容易にするためです.例えば、私たちのコードはgccのバージョンが少なくとも3.2.0以上であることを要求しています.私たちは次のような条件でコンパイルすることができます.
/* Test for GCC > 3.2.0 */
#if __GNUC__ > 3 || \
  (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
    (__GNUC_MINOR__ == 2 && \
      __GNUC_PATCHLEVEL__ > 0)))
  printf("gcc > 3.2.0
");
  //...
#endif


注意上記の条件コンパイル#ifの条件を複数行作成した場合(マクロ定義と同様、マクロ定義の1行が書き切れない場合は、最後に行継続記号'')、各行の最後の行継続記号''の後ろに記号、スペース、タブなどを付けてはいけません.彼は次の行も並列条件(通常は|または&&の右操作数)であることを示しています.通常はコンパイル前に行継続符''と前の改行符を削除し、同じ行と見なすことができます.
もちろん、上記の条件の大きさは非常に気に入らないと思っている人もいますが、理解するのも容易ではありません.このとき、私たちは自分でマクロGCCを定義することができます.VERSIONはgccバージョンを表すために使用され、原理も簡単です.主バージョン番号*10000+次バージョン番号*100+改訂バージョン番号を、最終的にこの値でgccのバージョン番号を判断します.
#include 
#define GCC_VERSION (__GNUC__ * 10000 \
                   + __GNUC_MINOR__ * 100 \
                   + __GNUC_PATCHLEVEL__)
int main()
{
/* Test for GCC > 3.2.0 */
#if GCC_VERSION > 30200
    printf("gcc > 3.2.0
"); //... #endif return 0; }


 
はい、そうです.GNUC__この予め定義されたマクロ変数は、特定のバージョンのgccに対してコードを記述するための基本的な理解があり、他の事前定義されたマクロについては、本稿が始まったばかりの頃に与えられたウェブサイトに行って見ることができ、それぞれの役割もよく書かれています.