在查看一些C ++ 03代码时,我发现了一个让我感到困惑的最烦恼的解析的实例:
#include <sstream>
#include <string>
int main(int, char** argv)
{
std::stringstream ss(std::string(argv[0]));
}
在上面的代码段中,ss
是一个函数的声明,它接受std::string*
并返回std::stringstream
。
std::string(argv[0])
如何被解析为std::string*
?
直觉上我认为argv[0]
明确无误访问argv
。
答案 0 :(得分:18)
原因是因为在函数声明的上下文中,编译器会将std::string(argv[0])
解释为std::string argv[0]
,即将零大小数组的声明解释为函数参数命名为 argv
(从argv
掩盖main
,因为这是一个不同的范围),然后等同于 array-的指针到指针衰减
因此,std::stringstream ss(std::string(argv[0]));
表示与std::stringstream ss(std::string* argv);
编辑:由于它在注释中被正确注释,零大小的数组声明在C ++中无效,导致程序格式错误。使用-pedantic
标志(GCC和clang)编译此代码时,将发出警告。 Visual Studio甚至会产生编译错误。对于除0以外的任何其他数组索引,上述论证仍然有效。
答案 1 :(得分:7)
我认为这来自&#34;声明语法就像表达式语法&#34;原则,以及&#34;阵列&#34;参数是指针。
以下数组声明是等效的:
int x[1];
int (x)[1];
int (x[1]);
或多或少,因为x[a]
,(x)[a]
和(x[a])
是等效表达式。
因此,
std::stringstream ss(std::string(argv[0]))
<=>
std::stringstream ss(std::string argv[0])
<=>
std::stringstream ss(std::string* argv)