优秀的编程知识分享平台

网站首页 > 技术文章 正文

C语言实践中定义自己的格式打印(2)

nanyue 2024-09-12 15:52:54 技术文章 7 ℃

使用 __attribute__((format(printf, 2, 3)))

主要目的是让编译器进行格式字符串和参数类型检查,这样可以在编译时捕获类似 printf 调用中的格式错误,确保日志函数的使用更安全。具体来说:

printf 是一个标准库函数,编译器可以检查它的格式字符串和参数类型。

__attribute__((format(printf, 2, 3))) 告诉编译器 TraceLog 函数的第2个参数是格式字符串,第3个参数及其后续参数是格式字符串的对应参数。

format()

GCC 编译器提供的一个函数属性(Function Attribute),用于指定函数的参数格式,主要用于像 printf 这样的函数,可以让编译器在编译时对函数调用进行参数检查,以捕获潜在的格式错误。

__attribute__((format(archetype, string-index, first-to-check)))
  • archetype:指定函数的行为类似于的标准函数,常见的值有 printf、scanf、strftime 等。
  • string-index:格式字符串在参数列表中的索引,从1开始计数。这个参数告诉编译器哪个参数是格式化字符串,例如 printf 中的第一个参数。
  • first-to-check:格式化字符串后面的第一个参数在参数列表中的索引,从1开始计数。这个参数告诉编译器从哪个参数开始进行参数类型检查,例如 printf 中的第二个参数。
  • 以下是一个示例,展示如何使用 format() 属性:

    #include <stdio.h>
    #include <stdarg.h>
    
    // 带有 format 属性的自定义函数
    void __attribute__((format(printf, 1, 2))) my_printf(const char *fmt, ...) {
        va_list args;
        va_start(args, fmt);
        vprintf(fmt, args);
        va_end(args);
    }
    
    int main() {
        // 使用自定义的带有 format 属性的函数
        my_printf("Hello, %s!\n", "world");
    
        return 0;
    }

    my_printf 函数的行为类似于 printf 函数。

    • 1 表示第一个参数是格式字符串。
    • 2 表示格式字符串后面的第二个参数开始,是对应的格式化参数。

    结论

    • 参数类型检查:能够在编译时捕获格式字符串和参数列表中的不匹配错误,防止因为这类问题导致的运行时错误。
    • 安全性和可靠性:提高函数调用的安全性和可靠性,特别是在处理用户输入或动态生成的格式化字符串时更为重要。

    格式打印(1)

    Tags:

    最近发表
    标签列表