çpreprocessor字符串化的怪事 [英] C preprocessor stringification weirdness

查看:135
本文介绍了çpreprocessor字符串化的怪事的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义计算结果为常量字符串宏,拿着文件名和行号,用于日志记录。

I am defining a macro that evaluates to a constant string, holding the filename and the line number, for logging purposes.

它工作正常,但我只是想不通为什么需要2个额外的宏 - 字符串化的ToString ,当直觉告诉干脆 __ FILE__:#__ LINE __

It works fine, but I just can't figure out why 2 additional macros are needed - STRINGIFY and TOSTRING, when intuition suggests simply __FILE__ ":" #__LINE__.

#include <stdio.h>

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define THIS_ORIGIN (__FILE__ ":" TOSTRING(__LINE__))

int main (void) {
  /* correctly prints "test.c:9" */
  printf("%s", THIS_ORIGIN);
  return 0;
}

这似乎只是一个丑陋的黑客攻击我。

This just seems like an ugly hack to me.

在详细说一下,这样 __ LINE __ 正确字符串化,并逐步发生阶段有人可以解释为什么既不 __ FILE__:字符串(__ LINE__ ) __ FILE__:#__ LINE __

Can someone explain in detail what happens stage by stage so that __LINE__ is stringified correctly, and why neither of __FILE__ ":" STRINGIFY(__LINE__) and __FILE__ ":" #__LINE__ works?

推荐答案

。该 GCC文档说:

宏参数是完全宏扩展它们代入宏体之前,除非它们字符串化或与其他标记粘贴。取代后,整个宏体,包括被取代的参数,再次扫描为要展开的宏。其结果是,参数扫描两次在他们扩大宏调用。

Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens. After substitution, the entire macro body, including the substituted arguments, is scanned again for macros to be expanded. The result is that the arguments are scanned twice to expand macro calls in them.

因此​​,如果该参数将字符串化,它也不会优先展开。你得到的括号内的文字文本。但如果它被传递给另一个宏时,它已展开。因此,如果你想扩展它,你需要宏的两个层次。

So if the argument will be stringified, it is not expanded first. You are getting the literal text in the parenthesis. But if it's being passed to another macro, it is expanded. Therefore if you want to expand it, you need two levels of macros.

这样做是因为在有些情况下,你做的不可以要扩大字符串化之前的说法,最常见的是断言()宏观情况。如果你写的:

This is done because there are cases where you do not want to expand the argument before stringification, most common being the assert() macro. If you write:

assert(MIN(width, height) >= 240);

您希望消息是:

Assertion MIN(width, height) >= 240 failed

而不是一些疯狂的事情MIN宏展开(海合会它使用几个特定的​​gcc的扩展,是相当长的IIRC)。

and not some insane thing the MIN macro expands to (in gcc it uses several gcc-specific extensions and is quite long IIRC).

这篇关于çpreprocessor字符串化的怪事的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆