引用内置类型的文字

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 表明 intdouble 文字也会发生这种情况。这发生在 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

other types of literal.

中的任何一项都不存在

另一种看待它的方式是重新检查您的代码

object func(char c, const char *s)
{
    return object{&c, s};
}

并注意字符串文字不是按值传递的。因为(一旦它衰减到指针)你只是传递第一个字符的地址 - 该数组必须至少在一段时间内保持有效,并且由于无法知道生命周期应该是多少,静态持续时间是一个合理的默认值。