c++ 怎么在宏定义控制打印log中输出Log的函数名

酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
CII Chap 04中,对于RETURN的宏定义是:
#define RETURN switch(Exception_stack = Exception_stack-&prev, 0) default: return
放在如下的代码中:
&&& /* do something */
&&& if (failed)
&&&&& RETURN 1;
EXCETPT(Allocation_Failed)
&&& /* Handle allocation fail */
展开之后就是:(暂不考虑TRY的宏定义)
&&& /* ... */
&&& if (failed)
&&&&&&& switch(Exception_stack = Exception_stack-&prev, 0)
&&&&&&& default:
&&&&&&&&&&& return 1;
EXCEPT(Allocation_Failed)
可以看到,这个宏的唯一目的,就是在return 1之前,执行Exception_stack = Exception_stack-&prev语句。
仔细考虑之后可以发现,C语言中其他的结构都不能满足这一条件。如果使用#define RETURN if(Exception_stack = Exception_stack-&prev, 1) return
则在if (...)& RETURN 1;else& ...语句中,会导致else的误匹配。
我想到的唯一一个功能相同的语言结构是:#define RETURN (Exception_stack = Exception_stack-&prev, 0) ((void)0) : return
#&&&ai-fans&发表于 01:04:00&&IP: 61.49.198.*
en, 真的很巧妙
#&&&XianChou&发表于 00:23:00&&IP: 210.82.77.*
#define RETURN(_X) do{if(Exception_stack = Exception_stack-&prev, 1) return _X}while(0)
#&&&傻强&发表于 09:54:00&&IP: 61.178.108.*
为什么起这么个文章名
#&&&周星星&发表于 08:44:00&&IP: 218.2.111.*
#define RETURN do( Exception_stack = Exception_stack-& return ) while(0) 行不行?
#&&&hanshuifang&发表于 17:44:00&&IP: 218.108.42.*
i want to ask : 1. why define RETURN macro instead use code directly? 2. Where else should this macro define helpful? and since i couldn"t find out the answer to these two question, so i don"t think this skill valuable!
#&&&无名&发表于 13:27:00&&IP: 202.105.42.*
#define ACE_RETURN(Y)
int __ace_error = ACE_Log_Msg::last_error_adapter ();
ACE_Log_Msg *ace___ = ACE_Log_Msg::instance ();
ace___-&set (__FILE__, __LINE__, Y, __ace_error, ace___-&restart (),
ace___-&msg_ostream (), ace___-&msg_callback ());
} while (0) 回复:C语言宏定义中的一个奇技淫巧
#&&&myan&发表于 15:09:00&&IP: 218.247.132.*
几位朋友的解决方案都不对。因为RETURN是要这样用的 func() { TRY //... // ... RETURN 10; EXCEPT // ... END_TRY }
#&&&周星星&发表于 12:13:00&&IP: 218.2.111.*
#&&&xjf&发表于 23:45:00&&IP: 218.19.121.*
可以解析一下,最后一句是什么意思? #define RETURN (Exception_stack = Exception_stack-&prev, 0) ((void)0) : return 没看明白
#&&&ypapa&发表于 11:04:00&&IP: 61.51.215.*
CII 是什么?机械工业出的《C语言接口与实现》?
#&&&刘未鹏&发表于 00:34:00&&IP: 222.94.3.*
不知道这样可不可以呢: #define RETURN return Exception_stack = Exception_stack-&prev, 例如: #define RETURN return i=0, double f() { int i=0; RETURN 0.99; ^^^^^^^^^ } int main() { double i= f(); std::cout&&i; //outputs 0.99 system(&pause&); }
#&&&perl-emacser&发表于 13:53:00&&IP: 210.22.158.*
一种利用macro定义函数的常用方法是: #define foo(_arg)
{ statement1; statement2; ... }while(0) 这个方法已被验证是可行的,可以添加任意多个语句,并且不会带来任何二义性。由于大家都这样用,这个定义也很容易理解,这已经是一种约定俗成的标准,而且linux内核里也是采用这个宏定义标准。它也并不是什么奇技淫巧!!!!!
#&&&赵老师&发表于 17:25:00&&IP: 165.170.128.*
奇技淫巧=奇巧淫技 可是糍粑没有收录,我生怕自己写错了
#&&&lodge&发表于 05:00:00&&IP: 61.183.79.*
#define RETURN switch(Exception_stack = Exception_stack-&prev, 0) default: return #define RETURN return Exception_stack = Exception_stack-&prev, #define RETURN(_X) do{if(Exception_stack = Exception_stack-&prev, 1) return _X}while(0) 这三种都可以,不过前两种好一点,不带参数的,更方便。而第二种在只用RETURN ;这是有语法错误,总的来说第一种最好。
#&&&peanut&发表于 16:48:00&&IP: 218.81.161.*
其实,尚有一种用for的方法(在我自己的实现里就是用for的,不知道那个编译出的代码更好一些), #define RETURN
for(Exception_stack = Exception_stack-& ;) return 当然,for的妙用还不至于此:)
#&&&agui&发表于 17:00:00&&IP: 211.151.91.*
&#define RETURN switch(Exception_stack = Exception_stack-&prev, 0) default: return &#define RETURN return Exception_stack = Exception_stack-&prev, &#define RETURN(_X) do{if(Exception_stack = Exception_stack-&prev, 1) return _X}while(0) &这三种都可以,不过前两种好一点,不带参数的,更方便。而第二种在只用RETURN ;这是有语法错误,总的来说第一种最好。 第二种如果不带返回值,语法会错误。 第三种逼着人用括弧,跟 return 不象。 开始想不明白为什么要用 switch 语句,后来想他可能是要用在只有一个语句的地方。如: if (xxxxx) RETURN &#define RETURN (Exception_stack = Exception_stack-&prev, 0) ((void)0) : return 冒号起什么作用啊?在C里好象冒号在标号(label)、case语句及:?中才有用,这里起什么作用呢?能编译通过吗? 这一句的前面部分看起来象是函数调用。编了一个程序试试发现通不过编译: $ cat t.c struct s { struct s* } *Exception_ #define RETURN (Exception_stack = Exception_stack-&prev, 0) ((void)0) : return void f() { RETURN; } int g() { RETURN 0; } 编译信息: $ gcc -c t.c t.c: In function `f": t.c:8: called object is not a function t.c:8: parse error before `:" t.c: In function `g": t.c:13: called object is not a function t.c:13: parse error before `:" PS: 以前以为switch语句必须要有大括号,从这里看来,也可以不要(因为只有return一句?),受教。
#&&&nydgg&发表于 23:14:00&&IP: 218.29.25.*
又想了几个:),不知能不能用 #define RETURN for (lhs= ; ) return #define RETURN while (lhs=rhs, 1) return 文章里的好像没写对,修改一下 #define RETURN lhs=rhs, 0? ((void)0) : return 还有 ? : 的 if 式 #define RETURN if (lhs=rhs, 0) ((void)0); else return
#&&&nydgg&发表于 23:24:00&&IP: 218.29.25.*
不好意思, ? : 式不能用。更正一下。
& 相关主题:2014年10月 C/C++大版内专家分月排行榜第三2014年4月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。C++库研究笔记——函数名的宏定义 - 推酷
C++库研究笔记——函数名的宏定义
GCC provides three magic variables that hold the name of the current function, as a string. The first of these is&
, which is part of the C99 standard:
The identifier&
&is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration
static const char __func__[] = &function-name&;
appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function.
__FUNCTION__
&is another name for&
. Older versions of GCC recognize only this name. However, it is not standardized. For maximum portability, we recommend you use&
, but provide a fallback definition with the preprocessor:
#if __STDC_VERSION__ & 199901L
# if __GNUC__ &= 2
define __func__ __FUNCTION__
define __func__ &&unknown&&
__PRETTY_FUNCTION__
&is yet another name for&
. However, in C++,&
__PRETTY_FUNCTION__
&contains the type signature of the function as well as its bare name. For example, this program:
extern &C& {
extern int printf (char *, ...);
void sub (int i)
printf (&__FUNCTION__ = %s\n&, __FUNCTION__);
printf (&__PRETTY_FUNCTION__ = %s\n&, __PRETTY_FUNCTION__);
main (void)
ax.sub (0);
gives this output:
__FUNCTION__ = sub
__PRETTY_FUNCTION__ = void a::sub(int)
These identifiers are not preprocessor macros. In GCC 3.3 and earlier, in C only,&
__FUNCTION__
__PRETTY_FUNCTION__
&were treate they could be used to initialize&
&arrays, and they could be concatenated with other string literals. GCC 3.4 and later treat them as variables, like&
. In C++,&
__FUNCTION__
__PRETTY_FUNCTION__
&have always been variables.
但是,根据,__FUNCTION__更保险?
On GCC you can use&
__FUNCTION__
__PRETTY_FUNCTION__
On MSVC you can use&
__FUNCSIG__
__FUNCTION__
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致下次自动登录
现在的位置:
& 综合 & 正文
总结几种log打印printf函数的宏定义
这里有篇不错的,[经验分享]日志中自动记录所在函数名、文件名、行号
比上面的要好多了:
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 c 类 输出log 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信