GCC中类似__LINE__,__FILE__,__FUNCTION__的预定义宏是在哪里定义的

时间:2022-01-12 17:06:29
小弟最近想研究一下GCC编译器,不知有没有高手指教一下GCC中的内置宏和函数(built-in function和类似__FILE__,__LINE__这样的预定义宏)是在哪里定义的?
我在GCC系统INCLUDE的头文件中似乎没有找到定义,是不是要去GCC源码里找?

31 个解决方案

#1


<stdio.h>

#2



Predefined Macros !
The compiler recognizes 10 predefined ANSI C macros.
include __FILE__ ,__LINE__ and so on. 

似乎查找不到定义吧,不过编译器却支持。这是预定义好的宏

#3


难道是内置在编译器中

#4


个人觉得是编译器内置的,应该不在头文件里。

#5


是啊,查不到定义,CPP预处理器却内置支持

有没有对GCC源码略有研究的大侠来指点一二...

#6


编译器内置的。。。

#7


引用 4 楼 lann64 的回复:
个人觉得是编译器内置的,应该不在头文件里。


我现在就是想研究一下,“内置”的含义。究竟是如何内置的。。。

比较无聊的问题吧,嗬嗬

#8


引用 7 楼 amw_jjj 的回复:
引用 4 楼 lann64 的回复:
个人觉得是编译器内置的,应该不在头文件里。 
 

我现在就是想研究一下,“内置”的含义。究竟是如何内置的。。。 

比较无聊的问题吧,嗬嗬


“内置”的含义就是定义在编译器的实现代码中,所以编译器本身就可以识别,不需要其他的头文件

#9


引用 8 楼 lbh2001 的回复:
引用 7 楼 amw_jjj 的回复:
引用 4 楼 lann64 的回复:
个人觉得是编译器内置的,应该不在头文件里。


我现在就是想研究一下,“内置”的含义。究竟是如何内置的。。。

比较无聊的问题吧,嗬嗬


“内置”的含义就是定义在编译器的实现代码中,所以编译器本身就可以识别,不需要其他的头文件


嗯,所以我就是问有没谁看过GCC源码,在内置宏定义,和内置函数这块。。

#10


没看过
帮顶

#11


以前见过, 是编译器内置的,两本种的一本,具体说不上来了

《c专家编程》《c..与缺陷》

#12


一直在用GCC.
也没见过包含这些的头文件.
估计是内置的.

#13


they are in <stdlib.h>
there are much more to be ventured.
Recommended books: <Learning Linux Programming in 24 Hours>, 
<Beginning learning Linux Programming> etc.

#14


学习......

#15


学习......

#16


引用 13 楼 hitlion2008 的回复:
they are in  <stdlib.h>
there are much more to be ventured.
Recommended books:  <Learning Linux Programming in 24 Hours>,
<Beginning learning Linux Programming> etc.


U sure? I failed to find it in GCC4

#17


编译器内置

#18


把编译器拉出来进行当场解剖看看.

#19


UP

#20


mingw g++ 有些宏啊



E:\>type main.cpp

#include <iostream>
using namespace std;

int main()
{
    cout<<__FILE__<<" "<<__LINE__<<" "<<__FUNCTION__<<endl;
    return 0;
}

E:\>g++ main.cpp

E:\>a
main.cpp 7 main

E:\>g++ --version
g++ (GCC) 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


E:\>



#21


- - 这些宏都是编译器提供的,不在文件中定义

#22


比如

编译器编译的时候 遇到 __FILE__ 会把它替换成当前它编译的文件名

#23


  __FILE__, __LINE__ 是ANSI C语言标准,各种C编译器都应当支持。而 __FUNCTION__ 是C99标准,故一些老的编译器就不支持。如gcc支持__FUNCTION__,而vc6就不支持。

重申一遍,这些宏是编译器内置宏,无法定义,也不需要定义,就如c语言关键字一样。

#24


的确没有,你grep __FILE__  /usr/include/*看看就知道了

#25


在 $(gcc_4.x.x)/cpp/ 目录下: 

init.c   : const struct builtin builtin_array
macro.c  : _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)


#26


__FILE__,__LINE__这种宏怎么可能预先在哪定义?他们的值是随着源文件被处理的过程而变化的,任何C或者C++的宏定义语法都不可能定义出这种宏来。这是编译器在做文法分析时根据分析上下文加上的

#27


他们只是看起来象,也有人称他们做宏,但是用C或者C++语法是定义不出这种宏语义的

#28


不是定义也不是宏
关键字吧

#29


引用 C语言核心技术(见http://www.china-pub.com/35853)
下面的37个关键字被C语言保留。
对编译器来说,每个关键字都有特定的意义,并且都不可以被用作标识符:

auto,break,case,char,const,continue,default,do,double,else,enum,extern,float,for,goto,
if,inline,int,long,register,restrict,return,short,signed,sizeof,static,struct,switch,
typedef,union,unsigned,void,volatile,while,_Bool,_Complex,_Imaginary



引用 http://blog.chinaunix.net/u2/67530/showart_601274.html 
以下内容转自 http://blog.chinaunix.net/u2/67530/showart_601274.html

作为一个C 程序员,可能经常遇到 __TIME__、__FILE__、__DATE__ 这样的宏,它们会在编译时,分别转换为包含编译时间、处理的转换单元名称及当前时间的字符串。

  在最新的ISO C标准中,如大家所知的C99,加入了另一个有用的、类似宏的表达式__func__,其会报告未修饰过的(也就是未裁剪过的)、正在被访问的函数名。请注意,__func__不是一个宏,因为预处理器对此函数一无所知;相反,它是作为一个隐式声明的常量字符数组实现的:

static const char __func__[] = "function-name"; 

  在function-name处,为实际的函数名。为激活此特性,某些编译器需要使用特定的编译标志,请查看相应的编译器文档,以获取具体的资料。

  有了它,我们可免去大多数通过手工修改,来显示函数名的苦差事,以上的例子可如下所示进行重写:

void myfunc()
{
cout<<"__FUNCTION__"<<endl;


  官方C99标准为此目的定义的__func__标识符,确实值得大家关注,然而,ISO C 却不完全支持所有的C99扩展,因此,大多数的编译器提供商都使用 __FUNCTION__ 取而代之,而 __FUNCTION__ 通常是一个定义为 __func__ 的宏,之所以使用这个名字,是因为它已受到了大多数的广泛支持。

  在Visual Studio 2005中,默认情况下,此特性是激活的,但不能与/EP和/P编译选项同时使用。请注意在IDE环境中,不能识别__func__ ,而要用__FUNCTION__ 代替。

  Comeau的用户也应使用 __FUNCTION__ ,而不是 __func__ 。

  C BuilderX的用户则应使用稍稍不同的名字:__FUNC__ 。

  GCC 3.0及更高的版本同时支持 __func__ 和__FUNCTION__ 。

  一旦可自动获取当前函数名,你可以定义一个如下所示显示任何函数名的函数:

#30


引用 25 楼 mLee79 的回复:
在 $(gcc_4.x.x)/cpp/ 目录下:

init.c   : const struct builtin builtin_array
macro.c  : _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)


thx~大侠!!

补充完整一下,在gcc源码的./libcpp/init.c中定义了一个常量结构体
#define B(n, t)    { DSC(n), t }
static const struct builtin builtin_array[] =
{
  B("__TIMESTAMP__",  BT_TIMESTAMP),
  B("__TIME__",  BT_TIME),
  B("__DATE__",  BT_DATE),
  B("__FILE__",  BT_FILE),
  B("__BASE_FILE__",  BT_BASE_FILE),
  B("__LINE__",  BT_SPECLINE),
  B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
  B("__COUNTER__",  BT_COUNTER),
  /* Keep builtins not used for -traditional-cpp at the end, and
     update init_builtins() if any more are added.  */
  B("_Pragma",  BT_PRAGMA),
  B("__STDC__",  BT_STDC),
};
在./libcpp/include/cpplib.h中定义了一个枚举类型
/* Different flavors of builtin macro.  _Pragma is an operator, but we
   handle it with the builtin code for efficiency reasons.  */
enum builtin_type
{
  BT_SPECLINE = 0, /* `__LINE__' */
  BT_DATE, /* `__DATE__' */
  BT_FILE, /* `__FILE__' */
  BT_BASE_FILE, /* `__BASE_FILE__' */
  BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
  BT_TIME, /* `__TIME__' */
  BT_STDC, /* `__STDC__' */
  BT_PRAGMA, /* `_Pragma' operator */
  BT_TIMESTAMP, /* `__TIMESTAMP__' */
  BT_COUNTER /* `__COUNTER__' */
};

而你提到的./libcpp/macro.c中的macro.c  : _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node),我在源码中也找到了注释和函数原型:

/* Helper function for builtin_macro.  Returns the text generated by
   a builtin macro. */
const uchar *
_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)

应该说,这确实不能算是传统意义上的“宏定义”

#31


回29楼的,我试验过CPP预处理器,确实发现__FUNCTION__或者__func__与__LINE__,__FILE__还不一样(上面的GCC源码也印证了这一点,那里没有定义__FUNCTION__或者__func__)

CPP预处理器会将__LINE__和__FILE__替换(和一般宏一样),但不会处理__FUNCTION__,从这个意义上说,__LINE__和__FILE__又是所谓的builtin macro,而__FUNCTION__不是,它更加特殊,它形似宏又不一样

这是我目前的理解,多谢各位

#1


<stdio.h>

#2



Predefined Macros !
The compiler recognizes 10 predefined ANSI C macros.
include __FILE__ ,__LINE__ and so on. 

似乎查找不到定义吧,不过编译器却支持。这是预定义好的宏

#3


难道是内置在编译器中

#4


个人觉得是编译器内置的,应该不在头文件里。

#5


是啊,查不到定义,CPP预处理器却内置支持

有没有对GCC源码略有研究的大侠来指点一二...

#6


编译器内置的。。。

#7


引用 4 楼 lann64 的回复:
个人觉得是编译器内置的,应该不在头文件里。


我现在就是想研究一下,“内置”的含义。究竟是如何内置的。。。

比较无聊的问题吧,嗬嗬

#8


引用 7 楼 amw_jjj 的回复:
引用 4 楼 lann64 的回复:
个人觉得是编译器内置的,应该不在头文件里。 
 

我现在就是想研究一下,“内置”的含义。究竟是如何内置的。。。 

比较无聊的问题吧,嗬嗬


“内置”的含义就是定义在编译器的实现代码中,所以编译器本身就可以识别,不需要其他的头文件

#9


引用 8 楼 lbh2001 的回复:
引用 7 楼 amw_jjj 的回复:
引用 4 楼 lann64 的回复:
个人觉得是编译器内置的,应该不在头文件里。


我现在就是想研究一下,“内置”的含义。究竟是如何内置的。。。

比较无聊的问题吧,嗬嗬


“内置”的含义就是定义在编译器的实现代码中,所以编译器本身就可以识别,不需要其他的头文件


嗯,所以我就是问有没谁看过GCC源码,在内置宏定义,和内置函数这块。。

#10


没看过
帮顶

#11


以前见过, 是编译器内置的,两本种的一本,具体说不上来了

《c专家编程》《c..与缺陷》

#12


一直在用GCC.
也没见过包含这些的头文件.
估计是内置的.

#13


they are in <stdlib.h>
there are much more to be ventured.
Recommended books: <Learning Linux Programming in 24 Hours>, 
<Beginning learning Linux Programming> etc.

#14


学习......

#15


学习......

#16


引用 13 楼 hitlion2008 的回复:
they are in  <stdlib.h>
there are much more to be ventured.
Recommended books:  <Learning Linux Programming in 24 Hours>,
<Beginning learning Linux Programming> etc.


U sure? I failed to find it in GCC4

#17


编译器内置

#18


把编译器拉出来进行当场解剖看看.

#19


UP

#20


mingw g++ 有些宏啊



E:\>type main.cpp

#include <iostream>
using namespace std;

int main()
{
    cout<<__FILE__<<" "<<__LINE__<<" "<<__FUNCTION__<<endl;
    return 0;
}

E:\>g++ main.cpp

E:\>a
main.cpp 7 main

E:\>g++ --version
g++ (GCC) 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


E:\>



#21


- - 这些宏都是编译器提供的,不在文件中定义

#22


比如

编译器编译的时候 遇到 __FILE__ 会把它替换成当前它编译的文件名

#23


  __FILE__, __LINE__ 是ANSI C语言标准,各种C编译器都应当支持。而 __FUNCTION__ 是C99标准,故一些老的编译器就不支持。如gcc支持__FUNCTION__,而vc6就不支持。

重申一遍,这些宏是编译器内置宏,无法定义,也不需要定义,就如c语言关键字一样。

#24


的确没有,你grep __FILE__  /usr/include/*看看就知道了

#25


在 $(gcc_4.x.x)/cpp/ 目录下: 

init.c   : const struct builtin builtin_array
macro.c  : _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)


#26


__FILE__,__LINE__这种宏怎么可能预先在哪定义?他们的值是随着源文件被处理的过程而变化的,任何C或者C++的宏定义语法都不可能定义出这种宏来。这是编译器在做文法分析时根据分析上下文加上的

#27


他们只是看起来象,也有人称他们做宏,但是用C或者C++语法是定义不出这种宏语义的

#28


不是定义也不是宏
关键字吧

#29


引用 C语言核心技术(见http://www.china-pub.com/35853)
下面的37个关键字被C语言保留。
对编译器来说,每个关键字都有特定的意义,并且都不可以被用作标识符:

auto,break,case,char,const,continue,default,do,double,else,enum,extern,float,for,goto,
if,inline,int,long,register,restrict,return,short,signed,sizeof,static,struct,switch,
typedef,union,unsigned,void,volatile,while,_Bool,_Complex,_Imaginary



引用 http://blog.chinaunix.net/u2/67530/showart_601274.html 
以下内容转自 http://blog.chinaunix.net/u2/67530/showart_601274.html

作为一个C 程序员,可能经常遇到 __TIME__、__FILE__、__DATE__ 这样的宏,它们会在编译时,分别转换为包含编译时间、处理的转换单元名称及当前时间的字符串。

  在最新的ISO C标准中,如大家所知的C99,加入了另一个有用的、类似宏的表达式__func__,其会报告未修饰过的(也就是未裁剪过的)、正在被访问的函数名。请注意,__func__不是一个宏,因为预处理器对此函数一无所知;相反,它是作为一个隐式声明的常量字符数组实现的:

static const char __func__[] = "function-name"; 

  在function-name处,为实际的函数名。为激活此特性,某些编译器需要使用特定的编译标志,请查看相应的编译器文档,以获取具体的资料。

  有了它,我们可免去大多数通过手工修改,来显示函数名的苦差事,以上的例子可如下所示进行重写:

void myfunc()
{
cout<<"__FUNCTION__"<<endl;


  官方C99标准为此目的定义的__func__标识符,确实值得大家关注,然而,ISO C 却不完全支持所有的C99扩展,因此,大多数的编译器提供商都使用 __FUNCTION__ 取而代之,而 __FUNCTION__ 通常是一个定义为 __func__ 的宏,之所以使用这个名字,是因为它已受到了大多数的广泛支持。

  在Visual Studio 2005中,默认情况下,此特性是激活的,但不能与/EP和/P编译选项同时使用。请注意在IDE环境中,不能识别__func__ ,而要用__FUNCTION__ 代替。

  Comeau的用户也应使用 __FUNCTION__ ,而不是 __func__ 。

  C BuilderX的用户则应使用稍稍不同的名字:__FUNC__ 。

  GCC 3.0及更高的版本同时支持 __func__ 和__FUNCTION__ 。

  一旦可自动获取当前函数名,你可以定义一个如下所示显示任何函数名的函数:

#30


引用 25 楼 mLee79 的回复:
在 $(gcc_4.x.x)/cpp/ 目录下:

init.c   : const struct builtin builtin_array
macro.c  : _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)


thx~大侠!!

补充完整一下,在gcc源码的./libcpp/init.c中定义了一个常量结构体
#define B(n, t)    { DSC(n), t }
static const struct builtin builtin_array[] =
{
  B("__TIMESTAMP__",  BT_TIMESTAMP),
  B("__TIME__",  BT_TIME),
  B("__DATE__",  BT_DATE),
  B("__FILE__",  BT_FILE),
  B("__BASE_FILE__",  BT_BASE_FILE),
  B("__LINE__",  BT_SPECLINE),
  B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
  B("__COUNTER__",  BT_COUNTER),
  /* Keep builtins not used for -traditional-cpp at the end, and
     update init_builtins() if any more are added.  */
  B("_Pragma",  BT_PRAGMA),
  B("__STDC__",  BT_STDC),
};
在./libcpp/include/cpplib.h中定义了一个枚举类型
/* Different flavors of builtin macro.  _Pragma is an operator, but we
   handle it with the builtin code for efficiency reasons.  */
enum builtin_type
{
  BT_SPECLINE = 0, /* `__LINE__' */
  BT_DATE, /* `__DATE__' */
  BT_FILE, /* `__FILE__' */
  BT_BASE_FILE, /* `__BASE_FILE__' */
  BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
  BT_TIME, /* `__TIME__' */
  BT_STDC, /* `__STDC__' */
  BT_PRAGMA, /* `_Pragma' operator */
  BT_TIMESTAMP, /* `__TIMESTAMP__' */
  BT_COUNTER /* `__COUNTER__' */
};

而你提到的./libcpp/macro.c中的macro.c  : _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node),我在源码中也找到了注释和函数原型:

/* Helper function for builtin_macro.  Returns the text generated by
   a builtin macro. */
const uchar *
_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)

应该说,这确实不能算是传统意义上的“宏定义”

#31


回29楼的,我试验过CPP预处理器,确实发现__FUNCTION__或者__func__与__LINE__,__FILE__还不一样(上面的GCC源码也印证了这一点,那里没有定义__FUNCTION__或者__func__)

CPP预处理器会将__LINE__和__FILE__替换(和一般宏一样),但不会处理__FUNCTION__,从这个意义上说,__LINE__和__FILE__又是所谓的builtin macro,而__FUNCTION__不是,它更加特殊,它形似宏又不一样

这是我目前的理解,多谢各位