C snprintf错误。sizeof的参数与destination相同

C snprintf错误。sizeof的参数与destination相同,c,gcc,printf,C,Gcc,Printf,gcc 4.8在生成时给我一个错误 #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; } 提供以下诊断信息: 警告:“void memset(void*,int,s

gcc 4.8在生成时给我一个错误

#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;
}
提供以下诊断信息: 警告:“void memset(void*,int,size_t)”调用中“sizeof”的参数与目标函数的表达式相同;你是想取消它的引用吗?[-Wsizeof指针memaccess] memset(p1,0,sizeof(p1));//错误 ^ 虽然这些警告不会导致编译失败,但-Wall通常与-Werror一起使用,因此,新的警告会变成新的错误。 要修复此问题,请重新写入以使用memcpy,或者取消引用有问题的memset调用中的最后一个参数*

在他们的例子中,很明显代码是错误的,但是在我的例子中,对于snprintf/strncpy,我不明白为什么,我认为这是gcc的一个错误positif错误。对吧?

感谢您的帮助。c:

#include <stdio.h>

void bar(char foo[1000])
{
    printf ("sizeof foo = %d\n", (int)(sizeof foo));
}

int main ()
{
    char foo[1000];
    bar(foo);
}
这就是为什么

static inline void toto(char str[3])
定义可以接受任何大小数组的函数。将忽略
3
,并将
str
视为指针(请尝试
printf(“%d\n”,sizeof(str))
:在我的机器上,它打印的是64位指针大小的8)。在这种情况下,编译器实际上是正确的

叮当声在这里给出了一个有用的警告:

test.c:6:25: warning: sizeof on array function parameter will return size of
      'char *' instead of 'char [3]' [-Wsizeof-array-argument]
    snprintf(str, sizeof(str), "XX"); 

当传递给函数时,数组将衰减为指向第一个元素的指针。那你有什么好处

静态内联void toto(char str[3]){..}

不是数组而是指针

因此,gcc发出了正确的警告

是否在函数参数中指定大小无关紧要,因为:

static inline void toto(char str[3])

它们都是等价的


请阅读以下内容:

在函数定义中,参数声明:

static inline void toto(char str[3])
不将
str
声明为数组(C没有数组类型的参数)。相反,它完全等同于:

static inline void toto(char *str)
3
被悄悄忽略

因此
sizeof(str)
与字符串可以容纳的字符数无关,它只是
char*
指针的大小

这是一条规则的结果,该规则表示使用数组类型声明的参数已“调整”为指针类型。这与在大多数上下文中数组类型的表达式隐式转换(或“衰减”)为指针的规则不同。这两条规则共同作用,使得处理数组的代码看起来像是直接处理数组,而实际上是处理指向数组元素的指针


C数组和指针之间的关系常常令人困惑。我建议你阅读本书的第6节;奇怪的是,
-Wsizeof pointer memaccess
的文档让我认为,如果您在第一个示例中编写了
char*str
,它会发出警告,但不应该为
char str[3]
发出警告。使用g++,我没有收到任何错误。使用gcc 4.8.1,我无法重现这个警告。当然,您使用的是
char-str[3]
,而不是
char*str
?是的,似乎在某些情况下它可能会起作用。因此,我更新了我的帖子,并提供了一个不起作用的例子。只要复制代码并运行gcc-Wall-Werror-o test main.c,您就会发现错误。我还有GCC4.8.1,我使用debian。(我在使用g++时也有此错误)
static inline void toto(char str[])
static inline void toto(char *str)
static inline void toto(char str[3])
static inline void toto(char *str)