c++ - ¿Por qué "extern const int n" no funciona como se esperaba?
declaration (5)
Mi proyecto consiste en solo dos archivos fuente:
a.cpp:
const int n = 8;
b.cpp:
extern const int n;
int main()
{
// error LNK2001: unresolved external symbol "int const n" (?n@@3HB)
int m = n;
}
Sé que hay varios métodos para hacerlo funcionar; sin embargo, solo me pregunto ¿POR QUÉ no funciona?
Declararlo externo en a.cpp y simplemente usar sin extern en b.cpp:
ah
extern const int n ;
a.cpp
#include "a.h"
...
const int n= 8
b.cpp:
#include "a.h"
...
int main()
{
int m = n;
}
Es porque const
implica vinculación interna por defecto, por lo que su "definición" no es visible fuera de la unidad de traducción donde aparece.
En este caso, la mejor solución es colocar la declaración ( extern int const n;
) en un archivo de cabecera, e incluir eso en a.cpp
y b.cpp
. El enlace está determinado por la primera declaración que ve el compilador, por lo que la definición posterior en a.cpp
tendrá el enlace correcto (externo).
Alternativamente, puede forzar el enlace en la definición:
extern int const n = 8;
A pesar de lo extern
, esta sigue siendo una definición; cualquier cosa con un inicializador fuera de una definición de clase es una definición.
Si las otras respuestas aquí no funcionan, puede ser que tenga sus definiciones en diferentes espacios de nombres ... si la compilación pasa, y obtiene un error de enlazador de undefined symbol
:
- verifique el espacio de nombres del símbolo indefinido; ese es el espacio de nombres efectivo para la declaración de
extern const int n
nterna. - asegúrese de que ese sea su espacio de nombres efectivo donde
const int n = 8
definiciónconst int n = 8
.
To share a const object among multiple files, you must define the variable as extern.
To define a single instance of a const variable, we use the keyword extern on both its definition and declaration(s):
A partir de estas reglas, solo necesita agregar la palabra clave extern
en su definición. ya lo tienes en declaración.
constexpr
variables const
y constexpr
en C ++ tienen un enlace interno (y por lo tanto no son accesibles en otra unidad de compilación) si no se declaran también extern
(ya sea en la definición o en una declaración previa).
En C, no es el caso (bien C no tiene constexpr
) por lo que su código es válido, y más puede poner extern
en una definición.
Entonces, si quieres escribir un código que sea tanto C como C ++ (y las dos declaraciones probablemente provengan del mismo encabezado que señaló James):
// a.cpp
extern const int n;
const int n = 8;
// b.cpp
extern const int n;
int main()
{
int m = n;
}
si no lo haces
// a.cpp
extern const int n = 8;
también es posible