return 传入的临时值并在同一语句中从中读取是否安全?
Is it safe to return a passed-in temporary value and read from it in the same statement?
我只是没有想太多就写了这篇文章。貌似还行,但不确定是否绝对安全。
class Foo
{
struct Buffer
{
char data [sizeof ("output will look like this XXXX YYYY ZZZZ")];
};
const char * print (const char * format = DEFUALT_FORMAT, Buffer && buf = Buffer ())
{
sort_of_sprintf_thing (format, buf .data, sizeof (buf.data), ...);
return buf .data;
}
};
std :: cout << Foo () .print ();
所以我认为语义是临时缓冲区将一直存在,直到整个cout
语句完成。是这样吗,还是在那之前它会超出范围,在这种情况下这是 UB?
是的,您的代码定义明确。
[class.temporary]
3 - [...] Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. [...]
[intro.execution]
11 - [ Note: The evaluation of a full-expression can include the evaluation of subexpressions that are not lexically
part of the full-expression. For example, subexpressions involved in evaluating default arguments (8.3.6) are
considered to be created in the expression that calls the function, not the expression that defines the default
argument. — end note ]
这并不意味着它特别 好 ,但是 - 将 Foo().print()
的结果绑定到 char const*
变量太容易了, 这将在下一个完整表达式中成为悬空指针。
代码有问题,问题不在调用站点上,而是在 print
函数上。您正在使用 rvalue(唯一会绑定到 rvalue-reference 的东西)并返回指向其内部结构的指针,这是 Undefined 的秘诀行为(如果用户取消引用返回的 const char*
)。
在您的特定示例中,Foo()
临时变量将存在足够长的时间,但此代码很容易让客户端将 const char*
存储在完整表达式之外并导致未定义的行为。
我只是没有想太多就写了这篇文章。貌似还行,但不确定是否绝对安全。
class Foo
{
struct Buffer
{
char data [sizeof ("output will look like this XXXX YYYY ZZZZ")];
};
const char * print (const char * format = DEFUALT_FORMAT, Buffer && buf = Buffer ())
{
sort_of_sprintf_thing (format, buf .data, sizeof (buf.data), ...);
return buf .data;
}
};
std :: cout << Foo () .print ();
所以我认为语义是临时缓冲区将一直存在,直到整个cout
语句完成。是这样吗,还是在那之前它会超出范围,在这种情况下这是 UB?
是的,您的代码定义明确。
[class.temporary]
3 - [...] Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. [...]
[intro.execution]
11 - [ Note: The evaluation of a full-expression can include the evaluation of subexpressions that are not lexically part of the full-expression. For example, subexpressions involved in evaluating default arguments (8.3.6) are considered to be created in the expression that calls the function, not the expression that defines the default argument. — end note ]
这并不意味着它特别 好 ,但是 - 将 Foo().print()
的结果绑定到 char const*
变量太容易了, 这将在下一个完整表达式中成为悬空指针。
代码有问题,问题不在调用站点上,而是在 print
函数上。您正在使用 rvalue(唯一会绑定到 rvalue-reference 的东西)并返回指向其内部结构的指针,这是 Undefined 的秘诀行为(如果用户取消引用返回的 const char*
)。
在您的特定示例中,Foo()
临时变量将存在足够长的时间,但此代码很容易让客户端将 const char*
存储在完整表达式之外并导致未定义的行为。