我有以下几点:
#include <stdio.h>
typedef struct {
char s[100];
} literal;
literal foo()
{
return (literal) {"foo"};
}
int main(int argc, char **argv) {
printf("%s", foo().s);
return 0;
}
编译时会出现此错误(使用gcc):
警告:格式'%s'需要类型为'char *'的参数,但参数为2 类型为'char [100]'[-Wformat =]
any1对如何修复它有任何想法?那个函数返回类型有什么问题?
修改 问题(如果在讨论中不清楚)是c标准gcc用来编译文件。如果你使用-std = c99或-std = c11就行了。
答案 0 :(得分:5)
这不是错误,而是警告,而不是-Wall
产生的所有警告都是明智的。
这里的编译器是&#34;种类&#34; right:在评估之前你的参数是一个数组而不是一个指针,并且获取一个临时对象的地址有点危险。我设法通过明确使用指针来消除警告
printf("%s\n", &foo().s[0]);
此外,您应该注意到您使用的是稀有动物,即临时生命的对象,返回值或您的函数。只有在C99之后,才有一个特殊的规则允许获取这样一个野兽的地址,但这是C语言的一个极端情况,你可能会通过使用一些更简单的结构更好。指针的生命周期以表达式的结尾结束。因此,如果您尝试将指针指定给变量,比如说,稍后在另一个表达式中使用它,则会出现未定义的行为。
编辑:正如mafso在评论中所说的,使用C99之前的C版本,不允许获取函数返回值的地址。正如Pascal Cuoq所说,即使对于C99,代码的行为也是未定义的,因为在参数的评估和函数的实际调用之间存在一个序列点。 C11通过产生我上面提到的临时生命对象来纠正这个问题。
答案 1 :(得分:-1)
我并不确切地知道为什么C语言比我更多的人可以解释它,但是以这种方式写main()
:
int main(int argc, char **argv) {
literal b = foo();
printf("%s", b.s);
return 0;
}
代码打印&#34; foo&#34;正确地在GCC 4.5.4
上