如何找到一些宏的来源

bas*_*bie 19 c c++ macros

定义宏有很多地方.当宏在我们自己的项目中定义时,很容易找到它们的定义位置.但是当我尝试学习一些着名的开源项目时,我经常被这个问题所困扰:在哪里找到宏的来源,如果我不能得到它的定义,我将无法理解它们中的一些(例如其中一些可以猜到他们的名字).例如,来自apache的一些声明:

#if defined(__osf__) && defined(__alpha),

#elif defined(__NSIG)
Run Code Online (Sandbox Code Playgroud)

据我所知,我知道宏有一些可能的起源地:

  1. 来自这个项目本身,在一些源文件中(这是最简单的,因为我们可以通过一些工具找到它)
  2. 从某些第三个lib的头文件中,我们可以grep它
  3. 来自c/c ++标准头文件(它们在linux中的哪个位置?)
  4. 来自os(他们在linux中的哪个位置?)
  5. 由配置工具自动生成(很苦,我不知道)
  6. 从像gcc/g ++这样的编译工具,或者在makefile中我们可以定义一些宏

我有一些问题需要咨询:

  1. 如何在os定义和gcc/g ++之间区分它们并配置工具生成的宏?它们分别具有一些特征吗?
  2. 如何找到os或标准C或编译器定义的源代码?例如,使用grepfind实用程序
  3. 如果__strange___通过梳理整个机器(cd /;grep __strange___ -r)无法找到一个宏,这意味着什么?

感谢您告诉原则和方法来区分它们,并找到它们的来源!

Nor*_*rtM 38

找到宏定义位置的一种简单,快速的方法是重新定义宏并检查编译器的警告/错误消息.

#include <windows.h>
#define min(a,b) nonsense

mintest.cpp(3) : warning C4005: 'min' : macro redefinition
    C:\Programme\Microsoft SDKs\Windows\v6.0A\include\windef.h(194) : see previous definition of 'min'
Run Code Online (Sandbox Code Playgroud)


Dav*_*men 13

  1. 如何在os定义和gcc/g ++之间区分它们并配置工具生成的宏?它们分别具有一些特征吗?

绝大多数是在某个头文件中定义的.gcc -dN -E在这里可以提供帮助.警告:如果使用此方法,则需要gcc -dN -E使用相同的包含路径,相同的-D<name>命令行选项,相同的环境变量(如CPATH...)调用,就像将源编译为目标文件时一样.

  1. 如何找到os或标准C或编译器定义的源代码?例如,使用grep或find实用程序

RTFM.阅读精细手册.

  1. 如果__strange__通过梳理整个机器无法找到一个宏,这意味着什么(cd /;grep __strange___ -r)

它可能只是意味着您的计算机上未定义该符号.假设有问题的代码来自一些开源软件包,它针对不同系统,不同编译器,其中一些不完全符合C++标准.典型的方法是#ifdef __some_bizarre_os__在代码的关键部分使用.该符号仅在运行Bizarre OS的机器上定义 - 而不是在您的机器上定义.

不幸的是,这不是唯一的情况.即使您的grep无法在任何地方找到它,也可能会定义符号.makefile可以连接两个字符串,-D__strange__形成编译器的单个命令行参数.该选项-D__strange__可能隐藏在makefile使用的一个环境变量中.某些项目所要求的〜/ .tcshrc文件可能令人难以置信.

更新
gcc -dM -E显示宏的定义,但不显示定义的位置.一个更好的选择是使用gcc -dN -E然后过滤掉不以首字母开头的行#.


piz*_*zza 5

gcc 编译器定义的宏可以通过

gcc  -dM -E a.c
Run Code Online (Sandbox Code Playgroud)

除此之外,它们都来自包含的文件和来源。

如果找不到宏,则意味着条件将被评估为 false。

您还可以使用 -v 选项,它会显示其默认包含目录的位置。

要找出宏来自哪个文件:

gcc -E $your_compile_options $your_c_file | \
egrep "^# " | grep -v '<'| cut -f 2 -d '"' | \
sort | uniq |
while read line
    do
            grep -l $your_macro $line
    done
Run Code Online (Sandbox Code Playgroud)