Pregunta

Leo y releo las cláusulas relevantes sobre ODR en el C ++ estándar, pero esta cuestión sigue abierta para mí. La norma dice que la definición de una función en línea se manifieste en cada unidad de traducción en el que se utiliza, y las definiciones será idéntica en un sentido que se describe en casi una página. Se dice que la secuencia de tokens debe ser el mismo. ¿Incluye los nombres de los identificadores locales?

En otras palabras ¿El programa siguiente violan el ODR? (He intentado poner a prueba a mí mismo con Visual Studio 2008 y tiene 0 errores y 0 advertencias. Pero supongo esto no prueba nada, porque entonces he cambiado el ejemplo de dos definiciones completamente diferentes y todavía tengo 0 errores y 0 advertencias. En excusa de MSVC cabe señalar que ninguna de diagnóstico es un requisito formal para violaciónes de ODR).

//main.cpp
inline int f(int);
int main(){
   f(3);
}
int f(int x){
   int z = x;
   return z*z;
}

//other.cpp
inline int f(int xx){
   int zz = xx;
   return zz*zz;
}
¿Fue útil?

Solución

Identificador es un tipo de ficha, cada identificador es una ficha separada, por lo que sí, es necesario tener el mismo identificador de respetar el ODR. Se puede hacer una diferencia en un compilador que detectan este (alguien listo para construir un ejemplo para Como con la plantilla exportada? Que puede detectar alguna violación de la ODR).

A continuación, hay una diferencia entre C y C ++ aquí. C no tiene el ODR en general y las reglas de función en línea en C99 (no hay funciones en línea en C90) son bastante diferentes a las de C ++. En C99, el código es correcto. De hecho se puede proporcionar completamente diferente definición. Una consecuencia es que en C (pero no en C ++), si se utiliza la misma definición y que la definición tiene un miembro estático, tiene, de hecho, la mayor cantidad de variables estáticas como TU utilizar la función.

Otros consejos

Sí, viola ODR. Utiliza diferentes secuencias de testigo, no sé qué es tan difícil de entender aquí.

Verificación de la ODR a través de las unidades de traducción es difícil (imposible) con técnicas de compilación tradicionales. La norma dice que "No hay diagnósticos necesarios", por lo que acaba de obtener un comportamiento indefinido.

Se puede obtener errores aún más sutiles cuando se utiliza, por ejemplo, dos clases diferentes definidos en unidades de traducción no relacionadas pero con el mismo nombre. Si hay una tabla virtual que puede entrar en conflicto sin mensajes de error (que pasó a mi amigo). Así siempre utilizar un espacio de nombres anónimos para las funciones y clases locales.

Los identificadores son tokens, luego por la misma secuencia de tokens de gobernar, el programa viola el ODR.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top