- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
对于任何大中型项目来说,将printf
替换为自定义日志功能是很常见的。这是一个最小的 C++ 示例及其用法:
#include <stdio.h>
#include <stdarg.h>
#include <string>
void log_printf(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap); // real code obviously does something fancier
va_end(ap);
}
int main() {
std::string x = "Hello";
// correct code
printf("String is %s\n", x.c_str());
log_printf("String is %s\n", x.c_str());
// incorrect code
printf("String is %s\n", x); // bad line 1
log_printf("String is %s\n", x); // bad line 2
}
简单记录器接收可变数量的参数并调用 vprintf
将它们输出到标准输出。 “正确代码”下的行演示了此记录器的正确用法。我的问题涉及“错误”行,其中错误地传递了字符串对象而不是指向字符缓冲区的指针。
在 GCC 4.6 下(在 Linux 下测试),坏行都不能编译,这是一件好事,因为我想捕捉到这种不正确的用法。错误是:
error: cannot pass objects of non-trivially-copyable type ‘std::string {aka struct std::basic_string<char>}’ through ‘...’
但是在 GCC 5.1 中,显然可以传递非平凡可复制的对象,并且编译成功。如果我使用 -Wall,那么只有“bad line 1”会发出关于意外参数类型的警告,但是带有 log_printf 的“bad line 2”在任何情况下都可以毫无问题地编译。不用说,两条线都会产生垃圾输出。
我可以用 -Wall -Werror
捕捉到“坏线 1”,但是“坏线 2”呢?我怎样才能让它也产生编译错误?
最佳答案
对于您自己的功能,您需要使用 common function attribute调用格式
:
void log_printf(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
void log_printf(const char* fmt, ...) {
...
}
请注意,该属性必须在函数声明中设置,而不是定义。
format
属性的第一个参数是样式,在本例中为 printf
(scanf
也是可能的,对于像这样工作的函数scanf
), 第二个参数是格式字符串,第三个参数是省略号 ...
所在的位置。它将帮助 GCC 检查格式字符串,就像标准 printf
函数一样。
这是一个 GCC 扩展,尽管其他一些编译器已经采用它来与 GCC 兼容,最著名的是 Intel C 编译器 ICC 和 Clang(在 OSX 和一些 BSD 变体上使用的标准编译器)。 Visual Studio 编译器没有这个扩展,我不知道 Visual C++ 有类似的东西。
关于c++ - 错误地将字符串传递给 printf 样式的日志函数时遗漏错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36407973/
我正在尝试运行某人给我的一些 C++ 代码。起初有一个指向 istream 文件的断开链接,我通过添加包含路径修复了这个问题: C:\Program Files (x86)\Embarcadero\R
谁能告诉我如何防止 .git 目录的内容被上传到 PyPi。我的 MANIFEST.in 看起来像这样: global-include *.py *.js *.rst *.html *.css *.l
最近在 typescript 项目的VSCode中遇到如下情况: 文件:some-interface.ts // no import statements have been skipped. Thi
为我找到这个问题的合适标题有点困难,所以也许这个例子会澄清我的问题。 我正在发出 ajax 请求以将一些变量从 JS 传递到 PHP。这些变量之一是带有一些选项的 URL,即 https://www.
我是一名优秀的程序员,十分优秀!