ANSI C:指向字符串字面量
是在ANSI C以下有效?
#include <stdio.h>
/* This returns "Hans" if arg != 0, "Gretel" if arg == 0 */
char* foo(int arg)
{
return arg ? "Hans" : "Gretel";
}
int main()
{
char* p_ch;
p_ch = foo(1);
printf("%s\n", p_ch);
p_ch = foo(0);
printf("%s\n", p_ch);
return 0;
}
代码在GCC/Linux下编译并运行良好。
的MinGW/Windows的说:
invalid conversion from `const char*' to `char*'
微软的Visual C/C++ 2008是细跟的代码。
- 我可以将
char*
变量分配给字符串,而不是在其初始化点吗? - 我读过字符串文字有
static
定位类。这是否意味着它们在它们所定义的功能之外是不可见的? - 自从
const
类型转换为非const类型时,它们是无效的吗?
是的,这是有效的标准C.但是,它只是有效的,因为字符串文字具有类型char[]
向后兼容;为了安全起见,您应该确保从foo
a const char*
的返回值。写入由foo
返回的任一字符串都会引发未定义的行为。
如果您的编译器对此抱怨,那么您可能意外地使用了C++编译器。在C++中,字符串文字的类型为const char []
。 (如果你改变char*
到const char*
,你的程序奇迹般地成为一个有效的C++程序也是如此。)
我可以将
char*
变量分配给一个字符串以外的其他地方,在它的初始点?
你的意思是
char *p;
// do some other stuff
p = "literal";
?是的,这是可能的。
我读过字符串文字有静态分配类。这是否意味着它们在它们所定义的功能之外是不可见的?
你混淆了静态分配和static
变量。您当然可以在另一个翻译单元中使用foo
的结果。
从什么时候开始,从常量类型到非常量类型的转换无效?
自1989年起正式将const
引入C.您必须明确地将const
关闭。
您从MinGW/Windows编译器获得的错误消息强烈建议您将此代码编译为C++。在C语言中,字符串文字有char[N]
类型(与C++中的const char[N]
相反)。在C语言中,你不应该得到这个错误信息。尽管如此,即使在C字符串中文字也是不可修改的,这意味着当指向字符串文字时坚持const char *
指针是一个好主意。
您的问题编号1有点奇怪。字符串文字是无名称对象,这意味着初始化是直接将指针指向字符串文字的唯一方法。没有别的办法。稍后,您可以将您的非常量指针复制到其他非常量指针,这是正确的。请记住,您不允许通过这些指针将任何东西写入字符串文字中:字符串文字是不可修改的。
你的问题2也没有多大意义。 “可见性”是名称的财产。字符串文字是无名称对象。它们在任何地方都不可见。他们不可见,因为他们没有名字。由于他们没有名字,所以“抓住”一个字符串文字并保持它的唯一方法是在指针初始化时附加一个指向它的指针(如你的例子)。可见度与它无关。字符串文字确实具有静态存储持续时间,这意味着它们“永远活着”:它们只要程序运行就存在。在您的示例中,即使在foo
退出后,字符串文字"Hans"
和"Gretel"
也会继续存在,这意味着由foo
返回的指针保持有效。
您的问题3的答案是:从C语言中从不存在的const指针到它们的非常量对应的隐式转换,即它始终是无效的。您必须使用显式强制转换才能执行此类转换。
我会声明'foo'返回'const char *'。当编译为C++时,代码变得无效。我不够标准的专家来解释为什么......我会希望GCC给出一些警告(但是即使是使用'-Wall -Wextra'的gcc 4.6也没有)。 –
@Basile,因为gcc正在编译C代码。在C中有这个_nothing_错误。如果你用g ++编译它,那将是另一回事,但显然如果你尝试编译完全有效的C代码,gcc并不认为它是一个问题。像“不能使用变量名'new''''''''''''''''''''''''''''可能有一天需要使用C++编译器编译这个''会令人讨厌:-) – paxdiablo
@BasileStarynkevitch:gcc -Wwrite-警告。这可能不是'-Wextra'的一部分,因为C库的某些部分可能依赖于此功能;例如'strerror'具有返回类型'char *',但可以使用字符串文字数组来实现。 –