引用内置类型的文字
Referring to literals of built-in type
所以我们 运行 对 Linux 的测试失败了,我想这源于我对引用内置文字的指针有效性的错误假设。该代码看起来类似于此伪代码:
auto obj = func( 'c', "str" ); // (1)
big_type big_object; // (2)
在 (1) 处,func()
returns 一个对象,它存储一个 const
指向字符文字的指针和一个指向字符串的指针文字。调试器中的检查表明两者都是正确的。
在(2)处,调试显示[=15=中的const char*
所引用的内存中原来是'c'
] 被覆盖。
Tets 表明 int
和 double
文字也会发生这种情况。这发生在 GCC 5.4.1 上,它不会发生在 GCC 4.1.2 上。
从事 C++ 工作超过 25 年,我学会了假设,通常情况下,编译器是对的,而我是错的;所以我在这里也这样做。
然而,虽然我知道,如果这只涉及小型内置类型的文字,我可以解决这个问题(通过复制它们而不是引用它们),如果这可能发生在任意大小的对象上("str"
) 还有,我们有一个很大的问题。
有人可以解释一下这方面的确切规则吗?
字符串文字在程序的整个生命周期中持续存在。字符文字不会,因为它们实际上只是整数,并且接受 none 对字符串的特殊处理。
换个角度来看:您的函数接收两个参数:一个是字符值,另一个是指向字符串文字的指针。制作指向字符串的指针的副本很好,但是创建指向作为参数传递的值的指针是不行的。如果您创建了一个指向字符串指针的指针,就会遇到麻烦。函数调用完成后,函数参数将被销毁。在字符的情况下,这意味着字符消失了,而在指向字符串的情况下,您已经制作了一个副本并保留了它。
来自[expr.prim.literal§1]:
A literal is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.
可以在 [lex.string§16]:
找到有关这些左值的更多精度
Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above. [...]
这直接解决了这个问题:字符串文字是唯一具有静态存储持续时间的文字,因此可以通过比它们出现的表达式更有效的指针来引用。
假设 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")
) ,那么临时变量将不复存在,你会留下一个杂散的指针。
对于单个字符,例如单个整数或浮点值,几乎不需要使用指向它们的指针。存储值。
具体规则,在string literals
上指出下面这句话大概就够了(虽然昆汀的标准引述显然更权威)
String literals have static storage duration, and thus exist in memory for the life of the program
中的任何一项都不存在
另一种看待它的方式是重新检查您的代码
object func(char c, const char *s)
{
return object{&c, s};
}
并注意字符串文字不是按值传递的。因为(一旦它衰减到指针)你只是传递第一个字符的地址 - 该数组必须至少在一段时间内保持有效,并且由于无法知道生命周期应该是多少,静态持续时间是一个合理的默认值。
所以我们 运行 对 Linux 的测试失败了,我想这源于我对引用内置文字的指针有效性的错误假设。该代码看起来类似于此伪代码:
auto obj = func( 'c', "str" ); // (1)
big_type big_object; // (2)
在 (1) 处,func()
returns 一个对象,它存储一个 const
指向字符文字的指针和一个指向字符串的指针文字。调试器中的检查表明两者都是正确的。
在(2)处,调试显示[=15=中的const char*
所引用的内存中原来是'c'
] 被覆盖。
Tets 表明 int
和 double
文字也会发生这种情况。这发生在 GCC 5.4.1 上,它不会发生在 GCC 4.1.2 上。
从事 C++ 工作超过 25 年,我学会了假设,通常情况下,编译器是对的,而我是错的;所以我在这里也这样做。
然而,虽然我知道,如果这只涉及小型内置类型的文字,我可以解决这个问题(通过复制它们而不是引用它们),如果这可能发生在任意大小的对象上("str"
) 还有,我们有一个很大的问题。
有人可以解释一下这方面的确切规则吗?
字符串文字在程序的整个生命周期中持续存在。字符文字不会,因为它们实际上只是整数,并且接受 none 对字符串的特殊处理。
换个角度来看:您的函数接收两个参数:一个是字符值,另一个是指向字符串文字的指针。制作指向字符串的指针的副本很好,但是创建指向作为参数传递的值的指针是不行的。如果您创建了一个指向字符串指针的指针,就会遇到麻烦。函数调用完成后,函数参数将被销毁。在字符的情况下,这意味着字符消失了,而在指向字符串的情况下,您已经制作了一个副本并保留了它。
来自[expr.prim.literal§1]:
A literal is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.
可以在 [lex.string§16]:
找到有关这些左值的更多精度Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above. [...]
这直接解决了这个问题:字符串文字是唯一具有静态存储持续时间的文字,因此可以通过比它们出现的表达式更有效的指针来引用。
假设 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")
) ,那么临时变量将不复存在,你会留下一个杂散的指针。
对于单个字符,例如单个整数或浮点值,几乎不需要使用指向它们的指针。存储值。
具体规则,在string literals
上指出下面这句话大概就够了(虽然昆汀的标准引述显然更权威)中的任何一项都不存在String literals have static storage duration, and thus exist in memory for the life of the program
另一种看待它的方式是重新检查您的代码
object func(char c, const char *s)
{
return object{&c, s};
}
并注意字符串文字不是按值传递的。因为(一旦它衰减到指针)你只是传递第一个字符的地址 - 该数组必须至少在一段时间内保持有效,并且由于无法知道生命周期应该是多少,静态持续时间是一个合理的默认值。