una - obtener clave primaria tabla sql server
Cómo usar correctamente la palabra clave externa en C (10)
" extern
" cambia el enlace. Con la palabra clave, se supone que la función / variable está disponible en otro lugar y la resolución se difiere al vinculador.
Hay una diferencia entre "extern" en las funciones y en las variables: en las variables no crea una instancia de la variable, es decir, no asigna ninguna memoria. Esto debe hacerse en otro lugar. Por lo tanto es importante si desea importar la variable de otro lugar. Para las funciones, esto sólo le dice al compilador que la vinculación es extern. Como este es el valor predeterminado (usa la palabra clave "estática" para indicar que una función no está vinculada mediante un enlace externo) no necesita usarla explícitamente.
Mi pregunta es acerca de cuándo se debe hacer referencia a una función con la palabra clave extern
en C.
No consigo ver cuándo se debe utilizar en la práctica. Mientras escribo un programa, todas las funciones que uso están disponibles a través de los archivos de encabezado que he incluido. Entonces, ¿por qué sería útil obtener acceso extern
a algo que no estaba expuesto en el archivo de encabezado?
Podría estar pensando en cómo funciona extern
incorrectamente, y si es así, corríjame.
Editar: ¿Debería realizar algo extern
cuando se trata de la declaración predeterminada sin la palabra clave en un archivo de encabezado?
Cuando tienes esa función definida en una dll o lib diferente, el compilador se desvía al enlazador para encontrarla. El caso típico es cuando llama a funciones desde la API del sistema operativo.
En C, ''extern'' está implícito para los prototipos de funciones, ya que un prototipo declara una función que se define en otro lugar. En otras palabras, un prototipo de función tiene enlazado externo por defecto; el uso de ''extern'' está bien, pero es redundante.
(Si se requiere un enlace estático, la función debe declararse como ''estática'' tanto en su prototipo como en el encabezado de la función, y estos deberían estar normalmente en el mismo archivo .c).
Funciones realidad definidas en otros archivos de origen sólo deben ser declaradas en las cabeceras. En este caso, debe usar extern cuando declare el prototipo en un encabezado.
La mayoría de las veces, sus funciones serán una de las siguientes (más como una mejor práctica):
- estático (funciones normales que no son visibles fuera de ese archivo .c)
- estático en línea (inline de .co .h)
- extern (declaración en los encabezados de la siguiente clase (véase más adelante))
- [ninguna palabra clave en absoluto] (funciones normales destinadas a ser accedidas usando declaraciones externas)
Muchos años después, descubro esta pregunta. Después de leer todas las respuestas y comentarios, pensé que podría aclarar algunos detalles ... Esto podría ser útil para las personas que llegan aquí a través de la búsqueda de gafas.
La pregunta es específicamente sobre el uso de funciones "externas", por lo que ignoraré el uso de "externas" con variables globales.
Definamos 3 prototipos de funciones.
//--------------------------------------
//Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
El código fuente principal puede usar el archivo de encabezado de la siguiente manera
//--------------------------------------
//Filename: "my_project.C"
#include "my_project.H"
void main(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 1234;
Para compilar y vincular, debemos definir "function_2" en el mismo archivo de código fuente donde llamamos a esa función. Las otras dos funciones podrían definirse en un código fuente diferente " .C" o podrían estar ubicadas en cualquier archivo binario ( .OBJ, * .LIB, * .DLL), para el cual es posible que no tengamos el código fuente.
Permite incluir de nuevo el encabezado "my_project.H" en un archivo "* .C" diferente para comprender mejor la diferencia. En el mismo proyecto, agregamos el siguiente archivo // --------------------------------------
//Filename: "my_big_project_splitted.C"
#include "my_project.H"
void old_main_test(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 5678;
int function_1(void) return 12;
int function_3(void) return 34;
Características importantes a tener en cuenta: cuando una función se define como "estática" en un archivo de encabezado, el compilador / vinculador debe encontrar una instancia de una función con ese nombre en cada módulo que use ese archivo incluido.
Una función que forma parte de la biblioteca de C se puede reemplazar en un solo módulo al redefinir un prototipo con "estática" solo en ese módulo. Por ejemplo, reemplace cualquier llamada a "malloc" y "gratis" para agregar la función de detección de pérdida de memoria.
El especificador "extern" no es realmente necesario para las funciones. Cuando no se encuentra "estática", siempre se supone que una función es "externa".
Sin embargo, "extern" no es el valor predeterminado para las variables. Normalmente, cualquier archivo de encabezado que defina que las variables sean visibles en muchos módulos debe usar "extern". La única excepción sería si se garantiza que un archivo de encabezado se incluya desde uno y solo un módulo.
Muchos gerentes de proyectos entonces requerirán que dicha variable se coloque al principio del módulo, no dentro de ningún archivo de encabezado. Algunos proyectos grandes, como el emulador de videojuegos "Mame", incluso requieren que dicha variable aparezca solo por encima de la primera función que los utiliza.
Si cada archivo en su programa se compila primero en un archivo objeto, entonces los archivos objeto están vinculados entre sí, necesita extern
. Le dice al compilador "Esta función existe, pero el código para ella está en otra parte. No se preocupe".
Todas las declaraciones de funciones y variables en los archivos de cabecera deben ser extern
.
Las excepciones a esta regla son las funciones en línea definidas en el encabezado y las variables que, aunque definidas en el encabezado, tendrán que ser locales a la unidad de traducción (el archivo de origen en el que se incluye el encabezado): estas deben ser static
.
En los archivos de origen, extern
no debe utilizarse para funciones y variables definidas en el archivo. Simplemente prefija las definiciones locales con static
y no haga nada por las definiciones compartidas; serán símbolos externos de forma predeterminada.
La única razón para usar extern
en absoluto en un archivo de origen es para declarar funciones y variables que están definidas en otros archivos de origen y para las cuales no se proporciona ningún archivo de encabezado.
La declaración de prototipos de funciones extern
es realmente innecesario. Algunas personas no les gusta porque solo desperdiciarán espacio y las declaraciones de funciones ya tienen una tendencia a desbordar los límites de línea. A otros les gusta porque de esta manera, las funciones y las variables se pueden tratar de la misma manera.
Un muy buen artículo sobre la palabra clave extern
, junto con los ejemplos: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
Aunque no estoy de acuerdo con que el uso extern
en las declaraciones de funciones sea redundante. Esto se supone que es una configuración de compilador. Así que recomiendo usar el extern
en las declaraciones de funciones cuando es necesario.
Ya se ha dicho que la palabra clave extern
es redundante para las funciones.
En cuanto a las variables compartidas entre las unidades de compilación, debe declararlas en un archivo de encabezado con la palabra clave externa, luego definirlas en un solo archivo fuente, sin la palabra clave externa. El único archivo de origen debe ser el que comparte el nombre del archivo de encabezado, para las mejores prácticas.
extern le dice al compilador que estos datos están definidos en algún lugar y que se conectarán con el enlazador.
Con la ayuda de las respuestas aquí y hablar con algunos amigos aquí es el ejemplo práctico de un uso de extern .
Ejemplo 1 - para mostrar una trampa:
File stdio.h:
int errno;
/* other stuff...*/
myCFile1.c:
#include <stdio.h>
Code...
myCFile2.c:
#include <stdio.h>
Code...
Si myCFile1.o y myCFile2.o están vinculados, cada uno de los archivos c tiene copias separadas de errno . Este es un problema ya que se supone que el mismo errno está disponible en todos los archivos vinculados.
Ejemplo 2 - La corrección.
File stdio.h:
extern int errno;
/* other stuff...*/
File stdio.c
int errno;
myCFile1.c:
#include <stdio.h>
Code...
myCFile2.c:
#include <stdio.h>
Code...
Ahora, si myCFile1.o y MyCFile2.o están vinculados por el enlazador, ambos apuntarán al mismo error . Así, resolviendo la implementación con extern .