以下函数返回的指针是否有效?
const char * bool2str( bool flg )
{
return flg ? "Yes" : "No";
}
它在Visual C++和g++中运行良好。C++标准对此有何规定?
关于存储持续时间:
2.13.4 普通字符串字面值和UTF-8字符串字面值也被称为窄字符串字面值。窄字符串字面值的类型为“长度为n的const char数组”,其中n定义为下面所述的字符串的大小,并且具有静态存储持续时间。
结合3.7.1阅读
3.7.1.
所有没有动态存储持续时间、没有线程存储持续时间并且不是本地的对象都具有静态存储持续时间。这些对象的存储将持续整个程序(3.6.2,3.6.3)。
关于类型:
附录C
子句2.13.4:
更改:将字符串字面值设置为const。字符串字面值的类型从“char数组”更改为“const char数组”。char16_t字符串字面值的类型从“某种整数类型的数组”更改为“const char16_t数组”。char32_t字符串字面值的类型从“某种整数类型的数组”更改为“const char32_t数组”。宽字符串字面值的类型从“wchar_t数组”更改为“const wchar_t数组”。
原理:这避免了调用不适当的重载函数,该函数可能期望能够修改其参数。
对原始特性的影响:改变了明确定义功能的语义。转换难度:简单的语法转换,因为字符串字面值可以转换为char*(4.2)。最常见的情况由新的但已弃用的标准转换处理:char* p =“abc”; //在C中有效,在C ++中已弃用 char* q = expr?“abc”:“de”; //在C中有效,在C ++中无效
使用范围:将字符串字面值视为指向可能修改的内存的指针的程序可能很少见。
动态分配的(在标准中似乎从未使用“堆”一词来描述内存区域)内存需要一个函数调用,该调用可能在静态内存分配之后很早就发生,甚至可以在main
函数中进行。
free
或delete
释放内存应该会引起诊断(参数类型不匹配)。因此,在这方面你也是安全的。 - dirkgently这段代码是有效的且符合标准。
字符串字面值存储在只读内存中,该函数只是获取所选字符串的地址。
C++标准(2.13.4)指出:
普通字符串字面值的类型为“n个const char的数组”,并具有静态存储期
理解这里的问题关键在于静态存储期:字符串字面值在程序启动时分配,并持续到程序结束。您的函数只是获取并返回其地址。
从技术上讲,是的,它是有效的。这些字符串具有静态存储持续时间。
但这还不是全部。
这些是C字符串。在C库和函数中的惯例是返回应该被释放的动态分配的字符串的指针。也就是说,返回的指针隐含地将所有权传递回调用者(通常在C中也有例外情况)。
如果您不遵循这些惯例,那么会混淆许多经验丰富的C开发人员,他们会期望这种约定。如果您不遵循这个标准的期望,那么它应该在代码中得到充分的记录。
此外,这是C++(根据您的标签)。因此,更常规的做法是返回std::string。原因是通过指针传递所有权仅仅是暗示的(这导致了许多错误,在C代码中违反了上述期望但已记录,不幸的是,代码的用户从未阅读过文档)。通过使用std::string,您正在传递一个对象,因此不再存在所有权问题(结果作为值传回,因此是您的),但由于它是一个对象,所以不存在任何资源分配的问题或疑问。
如果您担心效率,我认为这是一个虚假的担忧。
如果您想通过流打印此内容,那么已经有一个标准约定可以实现:
std::cout << std::boolalpha << false << std::endl;
std::cout << std::boolalpha << true << std::endl;