从根本上说,是的,从某种意义上说,它是安全的,因为它是静态的,所以价值将无限期地持续下去。
从某种意义上说,这是不安全的,因为您返回了一个指向变量数据的常量指针,而不是一个指向常量数据的变量指针。最好是不允许调用函数修改数据:
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;
}
更重要的是,这两种变体都返回一个指向常量数据的(变量)指针,因此用户不应该去修改字符串和(可能)践踏数组范围之外。(正如@strager 在评论中指出的那样,返回 aconst char *
并不能保证用户不会尝试修改返回的数据。但是,他们必须将返回的指针转换为非常量,然后再修改数据;这会调用未定义的行为,此时一切皆有可能。)
字面返回的一个优点是不写承诺通常可以由编译器和操作系统强制执行。该字符串将被放置在程序的文本(代码)段中,如果用户试图修改返回值所指向的数据,操作系统将产生错误(Unix 上的段违规)。
[至少有一个其他答案指出该代码不可重入;那是对的。返回文字的版本是可重入的。如果重入很重要,则需要修复接口,以便调用者提供存储数据的空间。]