问题标签 [preprocessor]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
12472 浏览

c++ - 是否有一个 C 预处理器可以根据定义/未定义的值消除 #ifdef 块?

原始问题

我想要的不是标准的 C 预处理器,而是它的变体,它可以从某个地方接受 - 可能是通过 -DNAME1 和 -UNAME2 选项的命令行 - 定义了哪些宏的规范,然后将消除死代码。

通过一些示例可能更容易理解我所追求的:

如果该命令使用“-DNAME1”运行,则输出为:

如果该命令使用“-UNAME1”运行,则输出为:

如果该命令在没有任何选项的情况下运行,则输出将与输入相同。

这是一个简单的案例 - 我希望代码也可以处理更复杂的案例。

用一个真实但仍然简单的例子来说明:

我想运行命令-DUSE_VOID -UPLATFORM1并获取输出:

另一个例子:

理想情况下,我想运行-UOLDUNIX并获得输出:

这可能会推动我的运气!

动机:具有大量条件代码的大型古老代码库。许多条件不再适用 - 例如,OLDUNIX 平台不再制造且不再受支持,因此无需在代码中引用它。其他条件始终为真。例如,通过条件编译添加功能,以便单个版本的代码可用于该功能不可用的旧版本软件和可用(或多或少)的新版本。最终,不再支持没有该功能的旧版本 - 一切都使用该功能 - 因此应该删除该功能是否存在的条件,并且“当功能不存在时”代码也应该删除。一世'

(该工具的一个非常聪明的版本可能会读取#include'd 文件以确定控制宏(在命令行上由 -D 或 -U 指定的那些)是否在这些文件中定义。我不确定这是否真的有用,除非备份诊断。不过,无论它做什么,伪预处理器都不能逐字扩展宏或包含文件。输出必须是类似于输入代码的源代码,但通常比输入代码更简单。)

状态报告(一年后)

经过一年的使用,我对所选答案推荐的“ sunifdef ”感到非常满意。它还没有出错,我也不希望它出错。我对它的唯一质疑是风格。给定一个输入,例如:

并使用“-UC”运行(C 从未定义),输出为:

这在技术上是正确的,因为 '&&' 比 '||' 绑定得更紧密,但这是一个公开的混淆邀请。我更希望它在 '&&' 条件集周围包含括号,如原文所示:

然而,鉴于我必须使用的一些代码的晦涩难懂,因为这是最大的挑剔是一种强烈的赞美;它对我来说是很有价值的工具。


街区新来的

在检查了上述信息中包含的 URL 后,我看到(如预期的那样)有一个名为Coan的新程序,它是 'sunifdef' 的继承者。它在 SourceForge 上可用,自 2010 年 1 月以来一直可用。我会检查它...今年晚些时候,或者明年,或者某个时候,或者永远不会有进一步的报告。

0 投票
3 回答
667 浏览

c - C 预处理器 - 用于家庭作业

任务:

您需要实现 C 预处理器。预处理器将作为命令行工具实现,其输入是 C 源文件(.c 扩展名),输出是预处理文件(.i 扩展名)。该工具也有几个选项。

$ cppr <options> file.c

成功处理后,将生成文件 .i。

<选项> 可能是:

预处理器选项
- -Aassertion -C -dD -dM -dN -Dmacro[=defn] -E -H
-idirafter dir -include 文件 -imacros 文件
-iprefixfile -iwithprefix dir -M -MD -MM -MMD
-nostdinc –P - Umacro –undef
目录选项
--Bprefix -Idir -I-

实现以上任意两项。这必须在需求阶段确定。

这些是 GCC 编译器定义的选项。请参阅 GCC 的手册页以了解这些选项。

您必须至少实现以下功能:

  1. 剥离评论
  2. #ifdef#endif
  3. #define对于常量(不是宏)
0 投票
70 回答
124438 浏览

c++ - 你遇到过的最糟糕的现实世界宏/预处理器滥用是什么?

您遇到过的最糟糕的现实世界宏/预处理器滥用是什么(请不要做作的 IOCCC 回答 *哈哈*

如果真的很有趣,请添加一个简短的片段或故事。目标是教一些东西,而不是总是告诉人们“永远不要使用宏”。


ps:我以前使用过宏......但通常当我有一个“真正的”解决方案时我最终会摆脱它们(即使真正的解决方案是内联的,所以它变得类似于宏)。


奖励:举一个宏确实比非宏解决方案更好的例子。

相关问题: C++ 宏何时有益?

0 投票
2 回答
1724 浏览

c - C 风格:宏还是预处理器?

我编写了一个库来将字符串与一组模式进行匹配,现在我可以轻松地将词法扫描器嵌入到 C 程序中。

我知道有许多完善的工具可用于创建词法扫描器(lex 和 re2c,仅列出想到的前两个)这个问题与词法分析器无关,而是关于“扩展”C 语法的最佳方法。词法分析器示例只是一般问题的具体案例。

我可以看到两种可能的解决方案:

  1. 编写一个预处理器,将带有嵌入式词法分析器的源文件转换为纯 C 文件,并可能转换为要在编译中使用的一组其他文件。
  2. 编写一组 C 宏来以更易读的形式表示词法分析器。

我已经做了这两个,但问题是:“根据以下标准,你认为哪一个更好?”

  • 可读性。词法分析器逻辑应该清晰易懂
  • 可维护性。查找和修复错误不应该是一场噩梦!
  • 干扰构建过程。预处理器在构建过程中需要一个额外的步骤,预处理器必须在路径中等等。

换句话说,如果你必须维护或编写一个使用这两种方法之一的软件,哪一种会让你失望更少?

例如,以下是针对以下问题的词法分析器:

  • 对所有数字求和(可以是十进制形式,包括像 1.3E-4.2 这样的指数形式)
  • 跳过字符串(双引号和单引号)
  • 跳过列表(类似于 LISP 列表: (3 4 (0 1)() 3) )
  • 在遇到单词 end(大小写无关)或缓冲区末尾时停止

在两种风格中。


如果有人对当前的实现感兴趣,代码在这里:http ://sites.google.com/site/clibutl 。

0 投票
1 回答
706 浏览

ant - 是否有可以从 Ant 调用的简单的预处理器/代码生成器,例如 GNU M4?

我需要维护一些旧的 XSL 代码,并且我发现 XSL 文件中有很多重复项。看起来 XSL 没有简单的包含/导入功能,它允许我将代码移动到不同的文件并在需要时包含它。

这听起来像是可以使用模型驱动开发工具来完成,但我只听说过它,并没有实际使用过它,而且它可能对这项工作来说太过分了。

是否有可以从具有包含/导入支持的 Ant 调用的简单预处理器?

0 投票
4 回答
288 浏览

java - Java - 防止多版本应用程序拆分代码库

我正在编写一个应用程序,它将以几个不同的版本发布(最初将存在大约 10 种代码库变体,并且需要维护)。当然,98% 左右的代码在不同的系统中是相同的,保持代码库完整是有意义的。

我的问题是 - 这样做的首选方法是什么?例如,如果我有一个在某些版本(MyClassDifferent)中不同的类(MyClass),并且该类在几个地方被引用。我希望根据我正在编译的应用程序的版本来更改该引用,而不必拆分所有引用 MyClassDifferent 的类。预处理器宏会很好,但是它们会使代码膨胀,而且 afaik 只有概念验证实现可用吗?

我正在考虑类似工厂模式的东西,以及每个应用程序的配置文件。有没有人有任何提示或指示?

0 投票
1 回答
402 浏览

preprocessor - 我可以看到着色器预处理器的输出吗?

我正在使用#defines,我根据程序状态将运行时传递给我的着色器源,以优化我的巨大着色器以降低复杂性。我想将优化的着色器写入文件,这样下次我运行程序时,我不必再次传递#defines,但我可以在程序启动期间直接编译优化的着色器,因为现在我知道什么样的着色器了按程序需要。

有没有办法从着色器预处理器中获取结果?我当然可以将#define 值存储到一个文件中,并基于该文件在程序启动期间编译着色器,但这不会那么优雅。

0 投票
1 回答
9293 浏览

visual-c++ - Visual C++:如何在代码中嵌入和显示编译时消息?

有没有办法在编译那段代码时在编译时显示的代码中嵌入一条消息?这些消息本质上是诊断性的,不应修改或中止编译过程。

(免责声明:我知道这个问题的答案。我没有在 Stack Overflow 上找到它,我认为这将是对知识库的有用补充。)

0 投票
1 回答
688 浏览

include - cl.exe Difference in object files when /E output is the same and flags are the same

I am using Visual Studio 2005's cl.exe compiler. I call it with a bunch of /I /D and some compilation/optimization flags (example: /Ehsc).

I have two compilation scripts, and both differ only in the /I flags (include directories are different). All other flags are the same. These scripts produce different object files (and not just a timestamp difference as noted below). The strange thing is that the /E output of both scripts is the same. That means that the include files are not causing the difference in object files, but then again, where is the difference coming from?

Can anyone elucidate on how I am seeing two different object files in my situation. If the include files are causing the difference, how come I see identical /E output?

PS. The object files are different not only in the timestamp, but in the code sections also. In fact the behavior of my final executable is different in both cases.

Edit: PSS: I even looked at the /includeFiles output of cl.exe and that output is identical. The object files, however, differ in more than just the timestamp (in fact, one is 1KB bigger than another!)

0 投票
3 回答
10320 浏览

iphone - 如何在 XCode 上检查我的 iPhone 应用程序的 TARGET_NAME?

我试图在同一个 XCode 项目中拥有我的 iPhone 应用程序的 2 个版本。代码库几乎相同,在我需要有不同行为的地方我决定使用预处理器的条件和${TARGET_NAME}标签。

我已将 设置OTHER_CFLAGS为包含“ -DTARGET_NAME=${TARGET_NAME}”。

然后在我的代码中我试图做

不幸的是,我总是打印出“lite”,因为TARGET_NAME == myApp它总是正确的:因为TARGET_NAME已定义。我一生都无法弄清楚如何评估这个字符串比较。任何的想法?

提前致谢