gpt4 book ai didi

c++ - 编译一个相当简单的c++ 11程序时gcc和clang之间的不同结果

转载 作者:IT老高 更新时间:2023-10-28 13:23:52 24 4
gpt4 key购买 nike

我试图了解 gcc 与 clang 在这个简单的 C++11 程序的输出中暴露的不同行为是否是由于 clang 中的错误(Xcode 5.0.2,OS X 10.8.5)。代码如下:

#include <iostream>

int main() {


int matrix[][3]{{1,2,3}, {4,5,6}, {7,8,9}};
auto dyn_matrix = new int[3][3]{{1,2,3}, {4,5,6}, {7,8,9}};

std::cout << matrix[0][1] << std::endl;
std::cout << dyn_matrix[0][1] << std::endl;

return 0;
}

如图所示,我正在尝试使用统一初始化来初始化大小为 3x3 的匿名(或命名)多维数组。从 MacPorts 使用 gcc 4.7 编译时,会获得预期的输出:

$g++-mp-4.7 -std=c++11 dyn_matrix.cpp -o dyn_matrix 
$ ./dyn_matrix
2
2
$

相反,如果使用 clang,则输出为:

$ clang++ -std=c++11 -stdlib=libc++ dyn_matrix.cpp -o dyn_matrix_clang
$ ./dyn_matrix_clang
2
4
$

在这种情况下,结果(显然)是错误的。 clang --version 报告:

Apple LLVM version 5.0 (clang-500.2.75) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix

该怪谁?我,gcc 还是 clang?

2013 年 12 月 11 日更新:该错误应该已在 r196995 中修复。不幸的是,我们仍然不知道 Apple 更新 Xcode 附带的 clang 版本需要多长时间。

2013 年 12 月 9 日更新:我提交了一份关于 LLVM bugzilla 平台的错误报告。确实已经被识别为bug,补丁正在审核中,见http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20131209/095099.html .

谢谢。

最佳答案

更新:感谢 Faisal Vali 和 Richard Smith,此错误已在 Clang ToT 中得到纠正;见test file由提交引入。


根据 §8.5.1 [dcl.init.aggr] 看来 Clang 是错误的:

11/ Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member. [ Example:

float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};

is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array y[0], namely y[0][0], y[0][1], and y[0][2]. Likewise the next two lines initialize y[1] and y[2]. The initializer ends early and therefore y[3]s elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0. In the following example, braces in the initializer-list are elided; however the initializer-list has the same effect as the completely-braced initializer-list of the above example,

float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};

The initializer for y begins with a left brace, but the one for y[0] does not, therefore three elements from the list are used. Likewise the next three are taken successively for y[1] and y[2]. —end example ]

我认为适用于 §5.3.4 [expr.new]:

15/ A new-expression that creates an object of type T initializes that object as follows:

  • If the new-initializer is omitted, the object is default-initialized (§8.5); if no initialization is performed, the object has indeterminate value.
  • Otherwise, the new-initializer is interpreted according to the initialization rules of §8.5 for direct initialization.

关于c++ - 编译一个相当简单的c++ 11程序时gcc和clang之间的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20452967/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com