snprintf错误。 sizeof的参数与目的地相同 [英] snprintf error. argument to sizeof is the same as destination

查看:2130
本文介绍了snprintf错误。 sizeof的参数与目的地相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我构建时,gcc 4.8给我一个错误

  #include< string.h> 
#include< stdio.h>

静态内联void toto(char str [3])
{
snprintf(str,sizeof(str),XX);
}

int main(){
char str [3];
toto(str);
返回0;
}

以下是gcc错误

错误:'snprintf'调用中的'sizeof'参数与目标表达式相同;你的意思是提供一个明确的长度吗?

注意:我使用-Wall -Werror标志将警告转换为错误。
$ b

这里有类似的东西
在一个评论中,有人回答了这个问题



对于固定长度的缓冲区,我通常使用strncpy(dest,src,sizeof(dest)); dest [ sizeof(dest)-1] ='\0';这保证了NULL终止,并且比snprintf更简单,更不用说很多人使用snprintf(dest,sizeof(dest),src);而是非常

但这是错误的:
gcc 4.8说



错误:'strncpy'调用中的'sizeof'参数与目标表达式相同;您的意思是提供明确的长度吗?[-Werror = sizeof-pointer-memaccess] strong>



在gcc 4.8文档中,他们正在讨论这个问题
他们说:



-Wall的行为已经改变,现在包含新的警告标志-Wsizeof-pointer-memaccess。这可能会导致代码中出现新的警告,这些警告与以前版本的GCC一起编译干净。

例如,

  include string.h 

struct A {};

int main(void)
{
obj;
A * p1 =& obj;
A p2 [10];

memset(p1,0,sizeof(p1)); //错误
memset(p1,0,sizeof(* p1)); // ok,取消引用
memset(p2,0,sizeof(p2)); //好的,数组
返回0;





给出以下诊断:
warning:argument to 'sizeof'in'void
memset(void *,int,size_t)'call与目标表达式相同;你的意思是解除引用吗? [-Wsizeof-pointer-memaccess]
memset(p1,0,sizeof(p1)); //错误
^
尽管这些警告不会导致编译失败,但是经常将-Wall与-Werror结合使用,因此,新的警告将转化为新的错误。
要解决这个问题,要么重写为使用memcpy,要么取消引用有问题的memset调用中的最后一个参数。*



那么,在他们的例子中,代码是错误的,但在我的情况下,与snprintf / strncpy,我不明白为什么,我认为这是一个gcc错误的positif错误。



感谢您的帮助

解决方案

传递给函数时指向第一个元素的指针。所以你有什么

static inline void toto(char str [3]){..}



不是一个数组,而是一个指针。

因此,gcc正确地警告。



是否在函数参数中指定大小并不重要:

  static inline void toto(char str [3])

  static inline void toto(char str [])

  static inline void toto(char * str)

都是相同的。



请阅读此处: 数组衰减?


gcc 4.8 give me an error when I build

#include <string.h>
#include <stdio.h>

static inline void toto(char str[3])
{
    snprintf(str, sizeof(str), "XX"); 
}

int main(){
    char str[3]; 
    toto(str);
    return 0;
}

Here is the gcc error

error: argument to ‘sizeof’ in ‘snprintf’ call is the same expression as the destination; did you mean to provide an explicit length?

Note: I m using -Wall -Werror flags which convert warning to error.

There is something similar here In a comment, someone answered this

"For fixed length buffers, I usually use strncpy(dest, src, sizeof(dest)); dest[sizeof(dest)-1] = '\0'; That guarantees NULL termination and is just less hassle than snprintf not to mention that a lot of people use snprintf(dest, sizeof(dest), src); instead and are very surprised when their programs crash arbitrarily."

But this is wrong: gcc 4.8 say

"error: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the destination; did you mean to provide an explicit length? [-Werror=sizeof-pointer-memaccess]"

in gcc 4.8 documentation, they are talking about this issue: they say:

The behavior of -Wall has changed and now includes the new warning flag -Wsizeof-pointer-memaccess. This may result in new warnings in code that compiled cleanly with previous versions of GCC.

For example,

include string.h

struct A { };

int main(void) 
{
    A obj;
    A* p1 = &obj;
    A p2[10];

    memset(p1, 0, sizeof(p1)); // error
    memset(p1, 0, sizeof(*p1)); // ok, dereferenced
    memset(p2, 0, sizeof(p2)); // ok, array
    return 0;
}

Gives the following diagnostic: warning: argument to ‘sizeof’ in ‘void memset(void*, int, size_t)’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess] memset(p1, 0, sizeof(p1)); // error ^ Although these warnings will not result in compilation failure, often -Wall is used in conjunction with -Werror and as a result, new warnings are turned into new errors. To fix, either re-write to use memcpy or dereference the last argument in the offending memset call.*

Well, in their example, it's obvious the code was wrong, but in my case, with snprintf/strncpy, I dont see why, and I think it's a false positif error of gcc. Right ?

thanks for your help

解决方案

An array decays into a pointer to the first element when you passed to a function. So what you have in

static inline void toto(char str[3]) {..}

is not an array but a pointer.

Hence, gcc rightly warns.

Whether you specify the size in the function parameter or not doesn't matter as:

static inline void toto(char str[3])

and

static inline void toto(char str[])

and

static inline void toto(char *str)

are all equivalent.

Read here on this: what is array decaying?

这篇关于snprintf错误。 sizeof的参数与目的地相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆