当一个数组由子表达式创建时,其中的临时变量会发生什么?

18
我读到了FDIS(12.2p {4,5})中的这两段文字:
引用第一段: 有两种情况下,临时变量的销毁时间点与完整表达式的结束时间点不同。第一种情况是调用默认构造函数来初始化数组元素时。如果构造函数有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,将顺序销毁创建于默认参数中的每个临时对象。

引用第二段: 第二种情况是将引用绑定到临时变量上。除非以下情况: [...]
- 通过函数调用(5.2.2)绑定到引用参数的临时变量将持续到包含该调用的完整表达式完成为止。
这两个情况似乎对于以下情况相互矛盾。
struct A {
  A() { std::cout << "C" << std::endl; }
  ~A() { std::cout << "D" << std::endl; }
};

struct B {
  B(A const& a = A()) { }
};

typedef B array[2];

int main() {
  array{};
}
这会输出所需的 CDCD 吗?还是按照第二个上下文所需输出 CCDD?GCC似乎遵循第二个上下文描述并输出 CCDD。我有没有忽视重要的东西?

编辑:我认为这不需要C++0x。我的问题也会影响此 new 表达式:

new array(); /* CDCD or CCDD ?? */

但在这种情况下,GCC遵循第一个上下文,并输出CDCD


希望一些GCC开发人员对此进行评论:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372。 - Johannes Schaub - litb
奇怪:我的GCC 4.6没有输出。--啊,我看到你有相同的表现问题 :) 就其价值而言:MSVS2010 SP1输出CDCD... - rubenvb
此外:8.5.4/4似乎暗示调用的参数通常没有顺序限制。这是否与GCC中的new array()情况相关,因为它会打印出CDCD - rubenvb
据我所见,这是一个缺陷(在标准的草案中)。但这是那些实际上并不重要的缺陷之一。 :-) - Cheers and hth. - Alf
1个回答

2
我不认为存在矛盾。
5.2.2明确说明了什么是函数调用。函数调用是后缀表达式,后面跟着包含可能为空的逗号分隔表达式列表的括号,这些表达式构成了函数的参数。
在您的程序中似乎没有对B::B(A const&)进行函数调用,因此我不知道第二段是如何适用的。
编辑上述内容可能是不正确的,鉴于1.9p10等。

1
虽然我同意有时候这可能有点不清楚,但在C++中,“函数调用”并不仅限于5.2.2规定的语法。它只是一个函数的调用,可以使用任何和所有的语法,也可以是隐式的。请参见1.9p15处的注释:“在C++中,几个上下文会导致函数调用的评估,即使翻译单元中没有相应的函数调用语法出现。[例如:对new表达式的评估会调用一个或多个分配和构造函数;请参见5.3.4。...--结束示例]”。 - Johannes Schaub - litb
大多数5.2.2适用于对函数的调用,而无论需要函数调用的上下文是什么。我引用的那个符号可能只是在显式使用函数调用语法时才使用(我认为这里有一些误解的空间,这是不幸的。特别是因为与5.2.2的交叉参考),但这似乎很奇怪,因为这意味着许多表达式模板节点会导致未定义的行为(因为它们只保留对传递给其构造函数的参数的引用,并在长时间运行其构造函数后引用它们)。 - Johannes Schaub - litb
@johannes 我会说确实有不幸的措辞,因为函数调用与运算符调用之间的区别确实很小。但是隐式调用是不同的。隐式调用不是表达式,因此不是任何完整表达式的一部分。有时根本没有表达式与这样的调用相关联(例如在声明上下文中)。所以我仍然认为第二个上下文不适用。 - n. m.
2
1.9p10适用:“完整表达式是不是另一个表达式的子表达式的表达式。如果语言结构被定义为产生函数的隐式调用,则对语言结构的使用在本定义的目的上被视为表达式。”请注意,在我的示例中,array{}已经是一个表达式(函数强制转换),new array()也是(新表达式)。 - Johannes Schaub - litb
在你引用的那段文字中,“将语言结构的使用视为表达式”是否意味着该结构本身是一个表达式,还是隐式调用是一个表达式?当我看到同一段落中以下代码示例的注释时,这个问题就开始了:S s1(1); // full-expression is call of S​::​S(int)。我也在stackoverflow上提出了这个问题:https://stackoverflow.com/questions/45744673/c-full-expression-standard-wording。谢谢。 - user42768

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接