- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设没有定义MACRO,这些是否等价
#ifdef MACRO
Not valid C or C++ code
#endif
/*
Not valid C or C++ code
*/
在 GCC 4.7.1 中,这似乎是等效的,但是否有预处理器做得更多?
最佳答案
这取决于您所说的“无效的 C 或 C++ 代码”是什么意思。
评论 中的文本不必符合大多数语言规则。它甚至没有被标记化。这是完全有效的:
/* This comment doesn't contain a valid sequence of preprocessing tokens
(because of the apostrophe). */
它必须遵守的唯一规则是控制注释结束位置的规则。人们经常在行注释中被反斜杠换行符绊倒(事实上,SO 的语法高亮器曾经犯过这个错误!)
// Line comment with ascii art ending with a \
Oops! This line is commented out too!
并且更少地(如果只是因为每个 C 教程都会警告您这一点)通过 block 注释而不是嵌套:
/* you can't nest /* block comments */ these words are not commented */
另一方面,“跳过”预处理器条件“组”中的文本确实必须符合某些语言规则。标准(C99 §6.10.1p5)的确切词是
Each directive’s condition is checked in order. If it evaluates to false (zero), the groupthat it controls is skipped: directives are processed only through the name that determinesthe directive in order to keep track of the level of nested conditionals; the rest of thedirectives’ preprocessing tokens are ignored, as are the other preprocessing tokens in thegroup.
有两个重要的位。首先,文本是标记化的,因此它确实必须是预处理标记的有效序列。
#if 0
This skipped conditional group doesn't contain a valid sequence of
preprocessing tokens (because of the apostrophe).
#endif
是语法错误。
$ gcc -fsyntax-only test.c
test.c:2:37: warning: missing terminating ' character
this skipped conditional group doesn't contain a valid sequence of
^
其次,指令仍然被部分处理“以跟踪嵌套条件的级别”,这意味着您可以这样做:
#if 0 // forget this entire mess
#ifdef __linux__
do_linux_specific_thing();
#elif defined __APPLE__
do_osx_specific_thing();
#elif defined _WIN32
do_windows_specific_thing();
#endif
#endif
而且你不能做这个:
#ifdef __linux__
do_linux_specific_thing();
#elif defined __APPLE__
do_osx_specific_thing();
#if 0 // forget windows
#elif defined _WIN32
do_windows_specific_thing();
#endif
#endif
(你不会得到最后一个错误,但是......
$ gcc -E -P -U__linux__ -D__APPLE__ -D_WIN32 test.c
do_osx_specific_thing();
do_windows_specific_thing();
……我不认为这是写它的人的本意。)
该语言的许多指南告诉您使用 #if 0
来“注释掉”您想暂时禁用的大块代码区域。他们这样说是因为 block 注释不会嵌套。如果您尝试禁用带有 block 注释的代码区域,但该区域中有 block 注释,则注释掉将过早结束并且代码可能无法编译。这在 C 没有行注释的时代更为重要;一些项目仅使用行注释进行注释,为禁用代码保留 block 注释。
但是因为 #if 0
… #endif
中的代码仍然是标记化的,并且嵌套的预处理器条件必须仍然平衡,所以你必须要小心你在哪里放入#if 0
和#endif
。这通常不是问题,因为在您禁用它之前用于编译的代码,所以它不应该包含任何导致标记化错误的内容。
关于c - #ifdef MACRO 是否等同于注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17104594/
是否可以传递带有宏触发器的字符串作为宏参数?请参阅下面的示例代码: options mprint; %let string5='%abc%def%'; %macro test(string); dat
我意识到我的代码的某个部分由看起来相似的方法组组成(就像我有多个三重奏:一个辅助函数被另外两个为程序员准备的函数调用)。我正在尝试编写一个宏来为我定义这三个函数,这样我需要做的就是调用宏。但我的尝试导
这个问题在这里已经有了答案: What can you do with Lisp macros that you can't do with first-class functions? (8 个回答
在 haxe 宏中,对于每个表达式,我们可以以 http://api.haxe.org/haxe/macro/Position.html 的形式获取它的位置。 : { file:String,
如果我评价 (def ^:macro my-defn1 #'defn) 定义了一个名为“my-defn1”的宏,我可以像使用“defn”一样使用它。 但是,如果我改为求值 (if true (de
我想知道这段代码输出背后的原因。我想不出答案。 #define f(a,b) a##b #define g(a) #a #define h(a) g(a) void main() { print
我正在尝试编写一个宏,该宏扩展为具有解构的 let 形式。我的问题是我想拥有以 let 形式定义的符号列表,包括通过解构获得的符号列表。 用例 我试图排除这种行为,例如验证: (let [a (foo
这段代码: macro FL(message) return @sprintf("%s:%d | %s", @__FILE__, @__LINE__, message) # line 2 en
此宏的目的是创建一个宏,该宏为访问关联列表的某个键提供名称。 (defmacro generate-accessor (key-symbol prefix) (let ((mac-name
在mcpp.exe --help Options available with only -@std (default) option: -@compat Expand recursive ma
鉴于: (define-syntax (test stx) (syntax-case stx () [(_ body ...) (with-syntax ([body0 (pro
Doug Hoyte 在他对 Let Over Lambda 的介绍中将 symb 函数定义为使用宏进行元编程的基本实用程序: 在剪辑中: (defun mkstr (&rest args) (w
我的代码需要两种模式,debug 和 verbose。我在头文件中将它们定义为, #define verbose TRUE #define debug TRUE 到目前为止,在我的代码中,我一直在使用
Set-macro-character 有一个名为 non-terminating-p 的可选参数。好像是用来表示读完宏字符后是否要读另一个字符,但是reader algorithm似乎忽略了这个论点
我一直在搜索,但几乎找不到关于 LibreOffice Basic 的信息 我有点习惯在 excel 中编写宏,但这次需要做一个循环,直到我到达第一个空列并且它需要在 libreoffice 中。 在
我正在尝试编写一个调用某些函数的宏。这些函数只能由宏使用,因此我将它们放在包装宏的 letfn 中。伪代码: (letfn [(fn-a [] ...) (fn-b [] ...)
我发现对于任何在 clojure.tools.macro 中编写类似 defn 的宏的人来说,这将是一个很棒的工具。图书馆:name-with-attributes功能。文档字符串说: To be u
假设: (defmacro testing (&optional var) `(list 'this 'is ,@(when (consp var) `('a 'list)))
在 SBCL 中,我可以使用以下内容获取函数的文档字符串: (documentation #'mapcar t) 但是,我不明白如何获取宏的文档字符串。例如,给定宏: (defmacro with-l
想了解 undef 和将宏定义为 0 之间的区别。谢谢。 最佳答案 #define MACRO 0 定义预处理器标记 MACRO成为文字 0 #undef MACRO 删除预处理器标记 MACRO 的
我是一名优秀的程序员,十分优秀!