大多数令人烦恼的解析,并访问阵列

Most vexing parse with array access

本文关键字:访问 阵列 烦恼 大多数      更新时间:2023-10-16

在查看一些C 03代码时,我找到了一个最烦人的parse parse 的实例,使我感到困惑:

#include <sstream>
#include <string>
int main(int, char** argv)
{
    std::stringstream ss(std::string(argv[0]));
}

wandbox上的实时示例

在上面的摘要中, ss是对 std::string*并返回 std::stringstream的函数的声明。

如何将std::string(argv[0])解析为std::string*

直觉上,我认为argv[0]是明确的访问argv

原因是因为在函数声明的上下文中,编译器将std::string(argv[0])解释为std::string argv[0],即零尺寸数组的A em 声明参数命名 argv(从 main中遮盖了 argv,因为这是一个不同的范围),然后与 array to-pointer-decay-decay 。。。P>

因此,std::stringstream ss(std::string(argv[0]));表示与std::stringstream ss(std::string* argv);

相同

编辑:由于在评论中正确注明了它,因此零尺寸的数组声明在C 中无效,使该程序不正确。在使用-pedantic标志(GCC和Clang)编译此代码时,将发出警告。Visual Studio甚至会产生汇编误差。对于任何其他数组索引,上面的论点仍然存在。

我相信,这是从"声明语法"中的,就像表达语法"原理",而"数组"参数是指示符。

以下数组声明是等效的:

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)