从根本上说,是的,它是安全的,因为它是静态的,它的值将无限期地持续下去。
从某种意义上说,您已经返回了一个指向变量数据的常量指针,而不是指向常量数据的变量指针,这并不安全。这是更好,如果调用函数不允许修改数据:
const char *GetString(void)
{
static char sTest[5];
strncpy(sTest, "Test", sizeof(sTest)-1);
sTest[sizeof(sTest)-1] = '\0';
return sTest;
}
在简单情况下所示,几乎没有必要担心缓冲区溢出,虽然我的代码版本不担心,并确保空终止。另一种方法是使用TR24731功能strcpy_s
代替:
const char *GetString(void)
{
static char sTest[5];
strcpy_s(sTest, sizeof(sTest), "Test");
return sTest;
}
更重要的是,这两个变种返回一个(变量)指针常量数据,因此用户不应该去修改字符串和(可能)践踏外阵列的范围。 (As @strager在注释中指出,返回const char *
并不保证用户不会尝试修改返回的数据,但是他们必须转换返回的指针,使其不是const,然后修改数据;这会调用未定义的行为,任何事情都有可能发生。)
字面返回的一个优点是通常可以通过编译器和操作系统来强制执行不写的承诺。该字符串将被放置在程序的文本(代码)段中,并且如果用户尝试修改返回值所指向的数据,操作系统将生成一个错误(Unix上的分段违例)。
[至少有一个答案指出代码不可重入;那是对的。返回文字的版本是可重入的。如果重入是很重要的,接口需要被固定,这样,来电提供了数据存储的空间]
“一般来说,他们应避免”可能是太强大了,但可以肯定的是你应该意识到风险和限制。为了澄清_why_其确定的+1。 – dmckee 2009-01-17 18:15:02
我同意dmckee,重入问题是因为在函数调用中静态设计是活着的。这不是不好的行为。但你的确应该知道风险。 – 2009-01-17 18:18:44