首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该如何规避-Wformat-truncation?

我应该如何规避-Wformat-truncation?
EN

Stack Overflow用户
提问于 2019-03-22 17:55:28
回答 2查看 651关注 0票数 1

假设我有一个函数,它接受一个int *p,我知道一个事实只指向0到99之间的值。但是,编译器并不知道这一点,所以如果我这样写:

代码语言:javascript
复制
char buffer[3];
snprintf(buffer, "%02d", *p);

我得到了一个警告(至少在GCC 8.x上)-它类似于:

代码语言:javascript
复制
warning: ‘%02d’ directive output may be truncated writing between 2 and 11 bytes into a region of size 2 [-Wformat-truncation=]
   snprintf(buffer, "%02d", *p);

我应该如何规避这个警告?

EN

回答 2

Stack Overflow用户

发布于 2019-03-22 17:55:28

我可以想出三种方法来避免警告:

使用GCC编译指示的

  1. 本地抑制:

#if __GNUC__ >= 8#杂注__GNUC__诊断推送#杂注GCC诊断忽略“-W格式截断”#endif snprintf( >=,"%02d",*p);#if __GNUC__>=8#杂注GCC诊断弹出#endif

  1. 无用地钳制打印值,以使编译器知道范围:

Buffer3 clamped_value =and print that instead of(*p,0),99)max*p`。snprintf(缓冲区,"%02d",clamped_value);

  1. 人为地将缓冲区大小增加9个字节;

字符buffer3+9;snprintf(缓冲区,"%02d",p);

但这些我都不太喜欢。第一种方法不太安全(而且更冗长);第二种方法浪费时钟周期,第三种方法浪费堆栈空间。

票数 2
EN

Stack Overflow用户

发布于 2020-01-31 01:58:52

这段代码在我的GCC 8.3.1上编译和运行得很好:

代码语言:javascript
复制
#include <stdio.h>

#define BUF_SZ 3

int main(void)
{
    int foo = 99;
    int *p = (int *)&foo;
    char buffer[BUF_SZ];

    snprintf(buffer, BUF_SZ, "%02d", *p);

    fprintf(stdout, "%s\n", buffer);

    return 0;
}
代码语言:javascript
复制
me@localhost:/tmp$ gcc -v 2>&1 | grep "gcc version"
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)

me@localhost:/tmp$ gcc -Wall test.c && ./a.out 
99

也许这个版本的GCC没有这个问题,但我在上面确实注意到你有snprintf(buffer, "%02d", *p); -它根本不应该编译,因为你缺少了snprintf的大小参数。

此外,值得注意的是,使用以下差异,GCC 8.3.1确实会像预期的那样抛出错误:

代码语言:javascript
复制
me@localhost:/tmp$ diff test.c test_format-truncation-warning.c
11c11
<     snprintf(buffer, BUF_SZ, "%02d", *p);
---
>     snprintf(buffer, BUF_SZ, "%03d", *p);

对于那些偶然发现本页面寻找更通用的-Wformat-truncation警告的“变通办法”的人。这里使用了memcpy(),尽管我怀疑-Wformat-truncation的作者是否打算将其用作strncpy()的替代方法。

代码语言:javascript
复制
#if USE_STRNCPY
    /* Note that using size of 'NAME_MAX' is just to prevent recent versions
     * of GCC from throwing '-Wformat-truncation' errors.  Otherwise, a char
     * buffer of len UUID_STR_LEN would be fine.
     */
    char tmp_fname[NAME_MAX + 1] = {0};
    strncpy(tmp_fname, input_file_name, NAME_MAX);
#else
    char tmp_fname[UUID_STR_LEN] = {0};
    memcpy((void *)tmp_fname, (void *)input_file_name,
           MIN(UUID_STR_LEN - 1, strnlen(input_file_name, UUID_STR_LEN - 1));
#endif
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55297018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档