std::basic_stringの「&foo[0]」は何を返すか

とあるコードを読んでいたら、

std::string foo = "abc";
printf("[%s]\n", &foo[0]); // [abc]

みたいな書き方をしていて「ん?stringなのに??」と思ったので、きちんと調べてみました。結論を書いてしまうと、

というルール2つによって、正しくC文字列のアドレスが返せているとわかりました。 …でも、こういう場合はstd::basic_string::c_str()を使うべきですよね、見にくいったらありません。