C++ C++;string.c_str()

C++ C++;string.c_str(),c++,undefined-behavior,C++,Undefined Behavior,如果使用g++和clang++,我得到++my string==my string##my string--。当MSVC和英特尔编译器编译时,它是+==我的字符串##我的字符串-- 为什么? #包括 #包括 使用名称空间std; 字符串测试() { string s0=“我的字符串”; 返回s0; } int main() { 字符串s=test(); const char*s1=test().c_str(); const char*s2=s.c_str(); cout在评论中,你问: 为什么t

如果使用
g++
clang++
,我得到
++my string==my string##my string--
。当MSVC和英特尔编译器编译时,它是
+==我的字符串##我的字符串--

为什么?

#包括
#包括
使用名称空间std;
字符串测试()
{
string s0=“我的字符串”;
返回s0;
}
int main()
{
字符串s=test();
const char*s1=test().c_str();
const char*s2=s.c_str();

cout在评论中,你问:

为什么
test().c_str()
可以工作,但
s1
不能

test().c_str()
仅适用于某些上下文,而不是所有上下文

std::cout << test().c_str() << std::endl;

是未定义的行为,因为在第一行执行完成之后,不需要临时活动。

在评论中,您询问:

为什么
test().c_str()
可以工作,但
s1
不能

test().c_str()
仅适用于某些上下文,而不是所有上下文

std::cout << test().c_str() << std::endl;

是未定义的行为,因为临时行为不需要在第一行执行完成后继续存在。

s1
指向一个不再存在的对象。从中读取它是明确的未定义行为。不要将未定义的行为与“从代码到汇编程序的未定义翻译”混淆。如果可观察行为(由语言定义的术语)保持不变,编译器可以以所选择的任何方式转换代码。它被称为.Why
test().c_str()
可以工作,但
s1
不能?除非将它放入变量中,否则从
test()返回的对象
在下一条语句开始之前(但在当前语句运行之后)立即被销毁。
s1
指向一个不再存在的对象。从该对象读取它是明确的未定义行为。不要将未定义行为与“从代码到汇编程序的未定义翻译”混淆。提供了可观察的行为(由于术语是由语言定义的)保持不变,编译器可以以所选择的任何方式转换代码。它被称为.Why
test().c_str()
的可能副本。c_str()
可以工作,但
s1
不能?除非将它放入变量中,否则返回的对象来自
test()
在下一条语句开始之前(但在当前语句运行之后)立即销毁。
char const* s1 = test().c_str();
std:cout << s1 << std::endl;