#define mmc_err(info, ...) \ do { \ printf("Info %s,%s,%d:"info"", __FILE__,__FUNCTION__,__LINE__,##__VA_ARGS__); \ } while(0)
时间: 2023-08-20 12:21:33 浏览: 116
这是一个 C 语言中的宏定义,它定义了一个名为 `mmc_err` 的宏,该宏接受一个字符串类型的 `info` 参数和可变参数 `...`。该宏的作用是在控制台上打印一条带有文件名、函数名、行号和参数信息的错误消息。
具体来说,该宏使用了 C 语言中的多行宏定义技巧,即在宏定义的末尾使用了一个 `do-while` 语句。这样可以确保宏定义中的所有语句都被视为一个整体,从而避免了一些潜在的问题。
该宏使用了 `printf()` 函数来打印错误消息。在打印消息时,使用了一些特殊的语法来将文件名、函数名和行号等信息插入到消息中。具体来说,使用了 `__FILE__`、`__FUNCTION__` 和 `__LINE__` 宏来分别获取当前文件名、函数名和行号,并使用了 `%s` 格式化字符串来将这些信息插入到消息中。另外,`##__VA_ARGS__` 用来表示可变参数,它可以将多个参数展开成一个参数列表传递给 `printf()` 函数。
因此,当你调用 `mmc_err()` 宏时,会在控制台上打印一条带有文件名、函数名、行号和参数信息的错误消息。例如,如果你调用了 `mmc_err("Error: %s", "something went wrong")`,那么会打印出类似于以下的错误消息:
```
Info myfile.c,myfunction,42: Error: something went wrong
```
相关问题
#define __KEEP(...) __VA_ARGS__
#define __KEEP(...) 这是一个预处理器宏(preprocessor macro),它通常用于C/C++编程中,特别是当需要在编译期间保留一组参数列表,而不想直接使用它们时。`__VA_ARGS__`是变量参数占位符,表示这一序列可以接受任意数量的位置参数。当你在代码中使用`__KEEP(__VA_ARGS__)`,编译器会把`__VA_ARGS__`替换为实际传递给宏的所有参数,通常用于日志记录、调试信息或者是生成模板代码等场景。
例如:
```cpp
void log(const char* format, ...) {
__KEEP(format, 42, "Hello", "World"); // 宏展开后类似于 printf(format, 42, "Hello", "World");
}
log("Log message: %d, %s, %s", __VA_ARGS__); // 日志将包含 42, Hello, World
```
#define LOG(fmt, ...) printf("[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)如果这个语句我没有写##_VA_ARGS_,会发生上面
如果你没有写##__VA_ARGS__,那么可变参数列表就无法传递给printf函数,编译器会提示错误。具体来说,编译器会认为printf函数只有三个参数(格式化字符串、__FILE__和__LINE__),而不是包含可变参数列表的函数,因此编译器会报错,提示缺少参数。
如果你不想使用可变参数列表,可以在宏定义中省略...和##__VA_ARGS__,直接将参数传递给printf函数,例如:
```
#define LOG(fmt) printf("[%s:%d] " fmt "\n", __FILE__, __LINE__)
```
在这个宏定义中,省略了可变参数列表,只有一个参数fmt表示日志信息的格式化字符串。这样定义的好处是,可以使用和printf函数类似的格式化字符串来输出日志信息,同时不需要传递可变参数列表,使得代码更加简洁、易读。但是,这种方式只能输出固定数量的参数,不能输出不同数量、不同类型的参数。
阅读全文