条件分配参考

MBo*_*ber 4 c++ gcc

能比我更深入了解C++标准的人能详细说明吗?

这是我的示例程序

#include <string>
#include <iostream>

int main(int argc, char* argv[]) {
    const std::string message("hello world");
    std::cout << std::hex << (void*)message.c_str() << std::endl;
    const std::string& toPrint = (argc > 0) ? message : "";
    std::cout << std::hex << (void*)toPrint.c_str() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在一台机器上它这样做:

# g++ --version && g++ str_test.cpp && ./a.out                  
g++ (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

0x9851014
0x9851014
Run Code Online (Sandbox Code Playgroud)

message并且toPrint似乎引用了我所期望的相同实例.但是,在另一台机器上,会发生这种情况

# g++ --version && g++ str_test.cpp && ./a.out 
g++ (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

0x7ffeb9ab4ac0
0x7ffeb9ab4ae0
Run Code Online (Sandbox Code Playgroud)

这看起来像编译器构造了一个messagefor 的副本toPrint.

根据C++标准,什么行为是正确的?或者它一般是不确定的?

Mar*_*ica 6

GLIBC写时复制字符串共享使您感到困惑.将您的测试程序更改为:

#include <string>
#include <iostream>

int main(int argc, char* argv[]) {
    const std::string message("hello world");
    std::cout << std::hex << (void*)&message << std::endl;
    const std::string& toPrint = (argc > 0) ? message : "";
    std::cout << std::hex << (void*)&toPrint << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(换句话说,打印字符串对象的地址,而不是包含文本的地址),两个平台都将返回不同的地址.

最新标准禁止写入拷贝(虽然我不明白究竟如何).在此之前它是合法的,但不是强制性的.(目前的想法是'小串优化'比牛更好 - 特别是在多线程世界中).

  • 也许[这个问题](http://stackoverflow.com/questions/12199710/legality-of-cow-stdstring-implementation-in-c11)正是您所寻找的. (2认同)