IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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++编译器都会支持,如果太老的编译器则不一定支持。这些宏都是以双下划线开头。

Macro Name

Description

__FILE__

此宏的内容将被扩展成当前输入的准备处理的文件名,数据格式是一个C的字符串常量。这是一个文件路径名,预处理器用此路径打开要处理的源文件。注意不是#include所指定的文件名,那个是缩短版。而是一个符合操作系统规范的可访问文件路径,比如绝对路径:"/usr/local/include/test.c",或者相对路径,“./test.c”或“test.c”。实际上,其内容就是编译器接收的文件参数。

这个宏,只表示使用这个宏的文件名,比如一个头文件使用了这个宏,再被包含在另一个文件中,这个宏还是显示头文件的名字。

__LINE__

这个宏将展开为代码当前行数,是一个十进制表示的整型常量。这个宏的定义,会随着每行的代码所变化。

这个宏,只表示使用这个宏的文件内行数,比如一个头文件使用了这个宏,再被包含在另一个文件中,这个宏还是显示头文件中的行数。

使用#line指令可以更改__LINE__的定义,比如#line 100,就指定下一行的行号是100.

__DATE__

这个宏展开为一个表示预处理器处理此文件的日期,是一个字符串常量。

显示格式为:"Feb 12 1996",“Aug??3 2022”,一共11个字符,当月份小于10,左边用空格填充。

如果GCC不能确定当前日期,编译过程每遇到一次会发出一个警告,宏的内容显示为"??? ?? ????"。

__TIME__

这个宏展开为一个表示预处理器处理此文件的时间,是一个字符串常量。

显示格式为:"23:59:01”,一共8个字符。

如果GCC不能确定当前时间,编译过程每遇到一次会发出一个警告,宏的内容显示为"??:??:??"。

__func__

这个宏是C99所引入的,但很早以来GCC一直使用的是__FUNCTION__。这两个都是字符串常量,表示当前的函数名。

但实际上这两个宏并不是真正的宏,因为预处理器是不知道当前的函数名的。

下面是GNU C扩展所常用的预定义宏:

Macro Name

Description

__BASE_FILE__

这个宏展开得到输入文件的名称,是一个C语言字符串常量。和上面的__FILE__类似。

这是在预处理器或C编译器的命令行中指定的源文件,针对的一个编译单元的源代码文件。

比如你在test.c中,包含了一个test.h,则test.h里面使用此宏,显示的还是test.c这个文件名。

__FILE_NAME__

这个宏扩展为当前输入文件的基本名称,以C语言字符串常数的形式出现。这是预处理器打开文件的路径名的最后一部分。例如,处理"/usr/local/include/myheader.h "将把这个宏设置为 "myheader.h"。

但这个我用Ubuntu中的GCC试验,不可用,显示未定义。

函数名字的字符串

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.

参考:

Function Names (Using the GNU Compiler Collection (GCC))

Top (The C Preprocessor)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:25:04  更:2022-08-06 10:25:17 
 
开发: 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年5日历 -2024/5/9 11:37:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码