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;
}
Run Code Online (Sandbox Code Playgroud)
这是gcc错误
错误:'snprintf'调用中'sizeof'的参数与目标的表达式相同; 你的意思是提供一个明确的长度?
注意:我使用-Wall -Werror标志将警告转换为错误.
这里有类似的东西 在评论中,有人回答了这个问题
"对于固定长度缓冲区,我通常使用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]"
-Wall的行为已更改,现在包含新的警告标志-Wsizeof-pointer-memaccess.这可能会导致代码中的新警告与以前版本的GCC一起干净地编译.
例如,
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;
}
Run Code Online (Sandbox Code Playgroud)
提供以下诊断:警告:'void memset(void*,int,size_t)'调用中'sizeof'的参数与目标的表达式相同; 你是不是要取消引用它?[-Wsizeof-pointer-memaccess] memset(p1,0,sizeof(p1)); // error ^虽然这些警告不会导致编译失败,但是-Wall经常与-Werror一起使用,因此新警告会变成新的错误.要修复,要么重写以使用memcpy,要么取消引用有问题的memset调用中的最后一个参数.*
好吧,在他们的例子中,显然代码是错误的,但在我的情况下,使用snprintf/strncpy,我不明白为什么,我认为这是gcc的错误positif错误.对 ?
谢谢你的帮助
传递给函数时,数组会衰减为指向第一个元素的指针.那么你有什么
static inline void toto(char str[3]) {..}
不是数组而是指针.
因此,gcc正确警告.
是否在函数参数中指定大小无关紧要:
static inline void toto(char str[3])
Run Code Online (Sandbox Code Playgroud)
和
static inline void toto(char str[])
Run Code Online (Sandbox Code Playgroud)
和
static inline void toto(char *str)
Run Code Online (Sandbox Code Playgroud)
都是等价的.
在这里阅读:什么是阵列衰减?
测试.c:
#include <stdio.h>
void bar(char foo[1000])
{
printf ("sizeof foo = %d\n", (int)(sizeof foo));
}
int main ()
{
char foo[1000];
bar(foo);
}
Run Code Online (Sandbox Code Playgroud)
跑步:
bash $ ./test
4
bash $
Run Code Online (Sandbox Code Playgroud)
这就是为什么。