2011-06-30 28 views
8

Hoy encontré una pecularidad que, aunque probablemente no es realmente importante, sin embargo me desconcierta. Quizás tampoco entiendo C++ correctamente.La vinculación interna implícita no es lo mismo que la vinculación interna explícita ("estática")?

Algunas matrices dentro de un punto de archivo de origen a los literales de cadena, así:

const char* a[] = { "a", "b", "c" }; 
const char* b[] = { "d", "e"}; 
const char* c[] = { "f", "g"}; 

Ninguno de estos arrays de punteros se utiliza nunca en ninguna otra forma que se pasa a GetProcAddress para recuperar un puntero de función de una biblioteca (este es un gestor/creador de funciones de OpenAL/EFX/captura dinámico sin bloqueo y creador/administrador de contexto).

Eventualmente se me ocurrió que probablemente debería declarar esas variables como static const ya que no son necesarias en ningún lugar fuera de ese mismo archivo .cpp, por lo que hacer enlaces internos explícitos parecía apropiado. Deberían tener enlaces internos de todos modos (ISO14882 3.5 (3)), por lo que solo estamos siendo buenos ciudadanos al hacer explícito lo que el compilador ya supone.

Hacer ese inocente cambio resultó en un aumento de 512 bytes en el tamaño del ejecutable. No como un 512b adicional realmente importa, pero simplemente no parecía tener sentido que exactamente lo mismo daría como resultado un código diferente. Como static const está en desuso (ISO14882 7.3.1.1 (2)), probé un espacio de nombres anónimo también, con el mismo resultado.

En cuanto a la fuente de ensamblador demuestra que la vinculación explícita interna (static o namespace{}) se moverán los literales de cadena en .rdata en lugar de .data y los literales de cadena se intercalan con el puntero a cadena literales matrices, en lugar de tener todo cadenas y todos los punteros en un bloque, respectivamente. Aquí probablemente también se encuentre la razón del diferente tamaño: muy probablemente la combinación de datos de una sección a otra haya afectado a una restricción de tamaño de sección. Curiosamente, los 3 sabores destruyen los nombres de manera diferente también.

Ahora me pregunto: ¿Estoy haciendo una falacia, si esos indicadores no tienen vinculación interna?

Además, en mi entendimiento const es ya de sólo lectura, es inhowfar static const "más de sólo lectura" (uno entra en .rdata y el otro no)?

Respuesta

7

Sus arreglos son no declarado const, por lo tanto, no son implícitamente enlace interno tampoco. Lo que tienes son matrices no const de punteros a const.

Dicho esto, no sé por qué esto afecta si las cadenas terminan en .rdata o .data.

+0

Oh mi, por supuesto ... qué error tan estúpido y obvio mío. De hecho, debe ser 'const char * const a []', que se comporta como se espera, también (vinculación interna implícita, y tiene idéntico mangling). También tiene sentido por qué los punteros-a-literal no constantes estarían en '.data', si la matriz no es const. Solo los literales, no sé ... Esperaría que fueran de solo lectura en cualquier caso. Aún así, excelente captura. – Damon

Cuestiones relacionadas