| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 编程参考 - C/C++中的方便调试使用的内置宏 -> 正文阅读 |
|
[C++知识库]编程参考 - C/C++中的方便调试使用的内置宏 |
当我们在调试代码时,经常需要打印log。这时就要输入函数名、文件名等信息,如果手动输入就很麻烦,每次都要输入不一样的内容。 而其实开发环境里里已经预定义了一些宏,方便我们使用。在预处理阶段,预处理器可以识别这些宏,简化我们的工作。 下面介绍标准的C/C++里面的一些相关预定义宏: 这个一般的C/C++编译器都会支持,如果太老的编译器则不一定支持。这些宏都是以双下划线开头。
下面是GNU C扩展所常用的预定义宏:
函数名字的字符串 GCC提供了三个神奇的常量,将当前函数的名称作为一个字符串保存。在C++11及以后的版本中,这三个常量都被当作常量表达式,可以用在需使用constexpr的上下文中。这些常量中的第一个是__func__,它是C99标准的一部分: 标识符 __func__ 被翻译器隐含地声明,就像在每个函数定义的开口括号之后,紧接着声明: static const char __func__[] = "function-name"; 其中 function-name 是语法上由两个大括号闭合的函数的名称。这个名字是函数的不加修饰的名字。作为扩展,在文件(或者在 C++ 的某个命名空间范围)中,__func__ 的值被定义为空字符串。 __FUNCTION__是__func__的另一个名字,是为了向后兼容旧版本的GCC而提供的。 在C语言中,__PRETTY_FUNCTION__是__func__的另一个名字,只是在文件范围内(或者在C++的某个命名空间范围内),它的值是字符串 "top level"。此外,在 C++ 中,__PRETTY_FUNCTION__ 包含了函数的签名和它的裸名。 比如: extern "C" int printf (const char *, ...);? class a {? public:? ?? ?void sub (int i)? ?? ?{? ?? ??? ?printf ("__FUNCTION__ = %s\n", __FUNCTION__);? ?? ??? ?printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);? ?? ?}? };? int main (void)? {? ?? ?a ax;? ?? ?ax.sub (0);? ?? ?return 0;? } 输出是: __FUNCTION__ = sub? __PRETTY_FUNCTION__ = void a::sub(int) 原版英文: Standard Predefined Macros The standard predefined macros are specified by the relevant language standards, so they are available with all compilers that implement those standards. Older compilers may not provide all of them. Their names all start with double underscores. __FILE__ This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ‘#include’ or as the input file name argument. For example, "/usr/local/include/myheader.h" is a possible expansion of this macro. __LINE__ This macro expands to the current input line number, in the form of a decimal integer constant. While we call it a predefined macro, it’s a pretty strange macro, since its “definition” changes with each new line of source code. __FILE__ and __LINE__ are useful in generating an error message to report an inconsistency detected by the program; the message can state the source line at which the inconsistency was detected. For example, fprintf (stderr, "Internal error: " ?????????????????"negative string length " ?????????????????"%d at %s, line %d.", ?????????length, __FILE__, __LINE__); An ‘#include’ directive changes the expansions of __FILE__ and __LINE__ to correspond to the included file. At the end of that file, when processing resumes on the input file that contained the ‘#include’ directive, the expansions of __FILE__ and __LINE__ revert to the values they had before the ‘#include’ (but __LINE__ is then incremented by one as processing moves to the line after the ‘#include’). A ‘#line’ directive changes __LINE__, and may change __FILE__ as well. See Line Control. C99 introduced __func__, and GCC has provided __FUNCTION__ for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function. They tend to be useful in conjunction with __FILE__ and __LINE__, though. __DATE__ This macro expands to a string constant that describes the date on which the preprocessor is being run. The string constant contains eleven characters and looks like "Feb 12 1996". If the day of the month is less than 10, it is padded with a space on the left. If GCC cannot determine the current date, it will emit a warning message (once per compilation) and __DATE__ will expand to "??? ?? ????". __TIME__ This macro expands to a string constant that describes the time at which the preprocessor is being run. The string constant contains eight characters and looks like "23:59:01". If GCC cannot determine the current time, it will emit a warning message (once per compilation) and __TIME__ will expand to "??:??:??". Common Predefined Macros The common predefined macros are GNU C extensions. __BASE_FILE__ This macro expands to the name of the main input file, in the form of a C string constant. This is the source file that was specified on the command line of the preprocessor or C compiler. __FILE_NAME__ This macro expands to the basename of the current input file, in the form of a C string constant. This is the last path component by which the preprocessor opened the file. For example, processing "/usr/local/include/myheader.h" would set this macro to "myheader.h". 6.50 Function Names as Strings GCC provides three magic constants that hold the name of the current function as a string. In C++11 and later modes, all three are treated as constant expressions and can be used in constexpr constexts. The first of these constants is __func__, which is part of the C99 standard: The identifier __func__ 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. As an extension, at file (or, in C++, namespace scope), __func__ evaluates to the empty string. __FUNCTION__ is another name for __func__, provided for backward compatibility with old versions of GCC. In C, __PRETTY_FUNCTION__ is yet another name for __func__, except that at file scope (or, in C++, namespace scope), it evaluates to the string "top level". In addition, in C++, __PRETTY_FUNCTION__ contains the signature of the function as well as its bare name. For example, this program: extern "C" int printf (const char *, ...); class a { public: ??void sub (int i) ????{ ??????printf ("__FUNCTION__ = %s\n", __FUNCTION__); ??????printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__); ????} }; int main (void) { ??a ax; ??ax.sub (0); ??return 0; } gives this output: __FUNCTION__ = sub __PRETTY_FUNCTION__ = void a::sub(int) These identifiers are variables, not preprocessor macros, and may not be used to initialize char arrays or be concatenated with string literals. 参考: |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:04:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |