【问题标题】:Run preprocessor only but with only for certain statements仅运行预处理器,但仅用于某些语句
【发布时间】:2012-02-01 13:20:21
【问题描述】:

我在一个程序中定义了许多调试语句,我希望能够在没有这些语句的情况下制作源代码的副本。

为了做到这一点,我首先查看了 GCC 的 -E 命令行参数,它只运行预处理器,但这远远超出了我的预期,扩展了包含的文件并添加了 #line 语句。

例如:

#include <stdio.h>

#ifdef DEBUG
    #define debug( s ) puts ( s );
#else
    #define debug( s )
#endif

int main( int argc, char* argv[] )
{
    debug( "Foo" )

    puts( "Hello, World!" );

    return 0;
}

我希望将其处理为:

#include <stdio.h>

int main( int argc, char* argv[] )
{


    puts( "Hello, World!" );

    return 0;
}

然后我可以用 astyle 之类的东西来整理它,而无需手动工作即可获得我想要的东西。

我是否缺少 GCC 的指令或者是否有工具能够做到这一点?

【问题讨论】:

  • 另外,考虑找到与这些行匹配的正则表达式并在您的编辑器中删除它们
  • 您可以编写一个非常简单的解析器并覆盖文件。

标签: c gcc c-preprocessor


【解决方案1】:

如果-E 没有帮助,请尝试使用-fdump-tree-all,如果你没有看到你想要的,那不是GCC 提供的(或)不是。

OTOH,这个问题已经在 SO 中进行了如下讨论,请参考以下内容以获得一些想法。

  1. Can gcc output C code after preprocessing?
  2. How do I see a C/C++ source file after preprocessing in Visual Studio?

希望对你有帮助!


嗨,垫子,

我看到你对@nos 的评论。但我手边有一个这样的脚本,所以与你分享。您可以尝试阅读我对类似问题的回答here

将以下代码复制到一个文件中,例如convert.sh。为该文件分配执行权限,chmod +x convert.sh 并按如下方式运行它:

$./convert.sh <filename>.c
$cat filename.c.done

&lt;filename&gt;.c.done 将有你需要的东西!

#!/bin/bash

if [[ $# -ne 1 || ! -f $1 ]] ; then
    echo "Invalid args / Check file "
    exit 
fi

file_name=$1

grep '^\s*#\s*include' $file_name > /tmp/include.c
grep -Pv '^\s*#\s*include\b' $file_name > /tmp/code.c
gcc -E /tmp/code.c | grep -v ^# > /tmp/preprocessed.c
cat /tmp/include.c > $file_name.done
cat /tmp/preprocessed.c >> $file_name.done

希望这会有所帮助!

【讨论】:

  • 如前所述,我知道 -E,但它做了太多的预处理,因为我只想解决一个语句。所以不,据我所知,这个问题以前没有讨论过。我会尝试-fdump-tree-all,但据我了解,这是为了在各种高级优化之后输出 AST。
  • @Mat 这是一个很好的问题,值得+1 ..所以我要+1!如果您遇到答案,请务必分享!
  • 注释掉文件中的#includes和其他宏,然后运行gcc -E
  • 正如@nos 提到的,注释掉#includes 并运行gcc -E mac.c | sed '/^\#/d'。有用! .. 我想用grep 写一个脚本来注释掉#includes 没什么大不了的!
  • @nos,因为这是我所看到的一样好的答案,您是否介意将其写为自己的答案,以便我可以将其标记为已回答。做了更多的研究,这是我知道的唯一有效的方法。
【解决方案2】:

gcc -E -nostdinc test.c 产生

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 9 "test.c"
int main( int argc, char* argv[] )
{


    puts( "Hello, World!" );

    return 0;
}

和 stderr 的错误

test.c:1:19: error: no include path in which to search for stdio.h

您可以轻松过滤掉 # 行...并重新添加包含。

【讨论】:

    【解决方案3】:

    使用 gcc 预处理器没有直接的方法可以做到这一点,但如果您只包含系统头文件,您可能会遇到gcc -E -nostdinc 的一些运气。

    但是,您可以注释掉 #include 指令和其他您不想处理的预处理器指令,并通过预处理器(gcc -Ecpp)运行代码,这样只有您想要的宏扩展(未注释掉的)被扩展。

    【讨论】:

      【解决方案4】:

      可以使用 unifdef、unifdefall 之类的工具——从代码中删除预处理器条件。 (Run a "light" preprocessor for GCC)

      【讨论】:

        【解决方案5】:

        我知道这个问题很老了,但现在确实有了答案。 “C 部分预处理器”正是这样做的。

        http://www.muppetlabs.com/~breadbox/software/cppp.html

        作为参考,如果其他人仍然想知道(我做了并找到了这个页面)。

        【讨论】:

          猜你喜欢
          • 2021-12-23
          • 1970-01-01
          • 1970-01-01
          • 2012-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多