提问人:sbi 提问时间:9/3/2018 最后编辑:sbi 更新时间:9/3/2018 访问量:146
引用内置类型的文本
Referring to literals of built-in type
问:
因此,我们在 Linux 上遇到了一个失败的测试,我想这源于我这边对引用内置文字的指针有效性的错误假设。该代码类似于以下伪代码:
auto obj = func( 'c', "str" ); // (1)
big_type big_object; // (2)
在 (1) 处,返回一个对象,该对象存储指向字符文本的常量指针和一个指向字符串文本的常量
指针。调试器中的检查显示两者都正确。func()
在 (2) 处,调试显示 const char*
in 中引用的内存中曾经的 a 被覆盖了。'c'
obj
Tets 表明这也发生在 和 字面上。这发生在 GCC 5.4.1 上,不会发生在 GCC 4.1.2 上。int
double
C++做了 >25 年,我学会了假设,通常,编译器是对的,我是错的;所以我也在这里做这件事。
但是,虽然我知道,如果这只涉及小型内置类型的文字,我可以解决这个问题(通过复制它们而不是引用它们),如果这也可能发生在任意大小的对象()上,我们有一个相当大的问题。"str"
那么有人可以解释一下这方面的确切规则吗?
答:
字符串文本在程序的整个生命周期中保持不变。字符文字则不然,因为它们实际上只是整数,并且没有对字符串进行任何特殊处理。
换个角度看:函数接收两个参数:一个是字符值,另一个是指向字符串文字的指针。复制指向字符串的指针是可以的,但创建指向作为参数传递的值的指针是不行的。就像你创建了一个指向指向字符串指针的指针一样。函数调用完成后,函数参数将被销毁。在字符大小写中,这意味着字符消失了,而在指向字符串的指针情况下,您已经制作了副本并保留了它。
从 [expr.prim.literal§1]:
文字是主要表达式。它的类型取决于它的形式。字符串文字是左值;所有其他文本都是 pr值。
有关这些左值的更多精度,请参见 [lex.string§16]:
计算字符串文本会生成一个具有静态存储持续时间的字符串文本对象,该对象从上面指定的给定字符初始化。[...]
这直接解决了这个问题:字符串文字是唯一具有静态存储持续时间的文字,因此可以由比它们出现的表达式更长的指针来引用。
评论
std::string("temp")
func()
func()
假设定义如下:func
some_class_type func(const char& ch, const char* str)
{
some_class_type some_object;
some_object.pch = &ch;
some_object.pstr = str;
return some_object;
}
然后,使用 存储指向临时变量的指针。&ch
的生存期不是完整的程序,直到完整表达式(即调用)结束,那么临时变量将不复存在,你只剩下一个杂散的指针。ch
func('c', "str")
对于单个字符,例如单个整数或浮点值,几乎不需要使用指向它们的指针。存储值。
对于确切的规则,指出以下关于字符串文字的句子可能就足够了(尽管昆汀的标准引用显然更权威)
字符串文本具有静态存储持续时间,因此在程序的生命周期内存中存在
对于任何其他类型的文字都不存在。
另一种看待它的方法是重新检查你的代码
object func(char c, const char *s)
{
return object{&c, s};
}
请注意,字符串文本不是按值传递的。因为(一旦它衰减到指针)你只是传递第一个字符的地址 - 该数组必须至少保持一段时间有效,并且由于没有办法知道生存期应该是多少,静态持续时间是一个合理的默认值。
上一个:stdlib 是否提供类型列表?
评论
'c'
const char *
&'c'
foo func(const char&, const char*)