ejecutar - Diferentes resultados entre gcc y clang al compilar un programa bastante simple de c++ 11
gcc linux (1)
Actualización: Gracias a Faisal Vali y Richard Smith, este error se corrigió en Clang ToT; ver el archivo de prueba presentado por la confirmación.
De acuerdo con §8.5.1 [dcl.init.aggr] , parece que Clang está equivocado:
11 / Las llaves se pueden elid en una lista de inicializadores de la siguiente manera. Si la lista de inicialización comienza con un paréntesis izquierdo, la siguiente lista separada por comas de cláusulas de inicializador inicializa los miembros de un subaggregado; es erróneo que haya más cláusulas de inicialización que miembros. Sin embargo, si la lista de inicialización de un subaggregado no comienza con un paréntesis izquierdo, solo se tomarán suficientes cláusulas de inicializador de la lista para inicializar los miembros del subaggregado; cualquier cláusula de inicializador restante se deja para inicializar el siguiente miembro del agregado del cual el subaggregado actual es miembro. [ Ejemplo:
float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, };
es una inicialización completamente arriostrada: 1, 3 y 5 inicializan la primera fila de la matriz
y[0]
, es decir,y[0][0]
,y[0][1]
, yy[0][2]
. Del mismo modo, las siguientes dos líneas inicializany[1]
yy[2]
. El inicializador finaliza temprano y, por lo tanto, los elementos dey[3]
se inicializan como si se inicializaran explícitamente con una expresión de la formafloat()
, es decir, se inicializan con0.0
. En el siguiente ejemplo, las llaves en la lista de inicializadores son elidas; sin embargo, la lista de inicializadores tiene el mismo efecto que la lista de inicializadores completamente arriostrados del ejemplo anterior,
float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
El inicializador para y comienza con un paréntesis izquierdo, pero el de
y[0]
no, por lo tanto, se utilizan tres elementos de la lista. Del mismo modo, los siguientes tres se toman sucesivamente paray[1]
yy[2]
. - ejemplo final ]
Lo cual creo que aplica debido a §5.3.4 [expr.new] :
15 / Una nueva expresión que crea un objeto de tipo T inicializa ese objeto de la siguiente manera:
- Si se omite el nuevo inicializador , el objeto se inicializa por defecto ( §8.5 ); si no se realiza la inicialización, el objeto tiene un valor indeterminado.
- De lo contrario, el nuevo inicializador se interpreta de acuerdo con las reglas de inicialización de §8.5 para la inicialización directa.
Estoy tratando de entender si el comportamiento diferente expuesto por gcc vs. clang en el resultado de este simple programa C ++ 11 se debe a un error en clang (Xcode 5.0.2, OS X 10.8.5). El código es el siguiente:
#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;
}
Como se muestra, estoy tratando de usar una inicialización uniforme para inicializar una matriz multidimensional anónima (con nombre) de tamaño 3x3
. Al compilar con gcc 4.7 desde MacPorts, se obtiene el resultado esperado:
$g++-mp-4.7 -std=c++11 dyn_matrix.cpp -o dyn_matrix
$ ./dyn_matrix
2
2
$
Por el contrario, en caso de que se use clang, la salida dice:
$ clang++ -std=c++11 -stdlib=libc++ dyn_matrix.cpp -o dyn_matrix_clang
$ ./dyn_matrix_clang
2
4
$
En este caso, el resultado es (aparentemente) incorrecto. clang --version
informes de 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
¿De quien es la culpa? yo, gcc o clang?
ACTUALIZACIÓN 11 de diciembre de 2013: El error debería haberse corregido en r196995. Lamentablemente, todavía no sabemos cuánto tiempo pasará antes de que Apple actualice la versión de clang que se envía con Xcode.
ACTUALIZACIÓN 9 de diciembre de 2013: Envié un informe de error sobre la plataforma LLVM bugzilla. De hecho, ha sido reconocido como un error, un parche se encuentra actualmente en revisión, consulte http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20131209/095099.html .
Gracias.