Creo que es una buena práctica declararlos como estáticos, ya que los hace invisibles fuera del módulo.¿Declaras que las funciones específicas de tu módulo son estáticas?
¿Qué piensas de esto?
Creo que es una buena práctica declararlos como estáticos, ya que los hace invisibles fuera del módulo.¿Declaras que las funciones específicas de tu módulo son estáticas?
¿Qué piensas de esto?
Si es realmente una función que es interna solo para ese archivo .c, entonces sí. Debería ayudar a evitar la contaminación del espacio de nombres global. Además, creo que el compilador puede hacer algunas optimizaciones con convenciones de llamadas si la función es estática ya que no sabe que ningún otro archivo fuente necesita saber cómo llamarlo. Esto solo se aplica realmente a c porque, como otros han notado, C++ tiene espacios de nombres para abordar este problema.
Si con 'módulo' solo quiere decir un archivo CPP, podría simplemente colocar la declaración y la definición en el archivo CPP.
Para C++, una mejor que la estática es ponerlo en un espacio de nombres sin nombre (anónimo). Esta es la forma preferida de evitar la contaminación del espacio de nombres global.
namespace {
void myLocalFunction() {
// stuff
}
}
Otra ventaja sobre los espacios de nombres anónimos es que aún puede pasar la dirección de los objetos dentro de las plantillas, ya que todavía tienen vinculación externa. –
+1, se encontró más información en este hilo SO: http://stackoverflow.com/questions/154469/unnamedanonymous-namespaces-vs-static-functions#154482 – luke
desventaja de que no es útil en C. La pregunta era sobre c/C++ – Ilya
creo que C y C++ tienen diferentes limitaciones relativas static
: en C que no tiene espacios de nombres y archivos .c son sus módulos, por lo que es muy, muy importante poner todas las funciones no públicas como estática para prevenir errores!
En C++, se debe utilizar un espacio de nombres en el anonimato, así:
// foo.cpp
namespace
{
class Core { ... };
void InternalFandango(Core *);
}
void SomeGloballyVisibleFunction()
{
InternalFandango(&core);
}
Ventaja: esto es aplicable a struct declaraciones/clase, también.
En C, simplemente marque las funciones "estático". No hay nada en contra de usar "estático" en C++, también, pero he aprendido a preferir el espacio de nombres, ya que es un concepto único que funciona para todas las declaraciones.
eso está mal. las variables son externas las constantes son estáticas. –
Sí, esto es incorrecto, debe editar su respuesta para corregir esto, o ¡podría ser rechazado! –
Gracias chicos - esto es realmente extraño ... – peterchen
Sobre la única propiedad potencialmente útil que puedo pensar para este uso de "estática" en C++, que los espacios de nombres anónimos no proporcionan, es que hay una advertencia en GCC que puede activar para funciones estáticas no utilizadas (un formulario de código muerto). No lo obtiene para las funciones no utilizadas en espacios de nombres anónimos, por lo que, en el caso improbable de que desee que el compilador le diga cuándo deja de usar la función, hágalo de esa manera.
Hubo muchos detalles sobre la implementación y no demasiado sobre el concepto.
Limitar el alcance de la variable/función, etc. es una buena práctica. Este es un concepto básico de diseño orientado a objetos; desea mantenerlo privado como privado. De esta manera, su interfaz es más limpia y el mantenimiento del código es más fácil. Y un día no encontrará que cambiar algo que consideraba una compilación privada se rompió porque a alguien en otra parte del proyecto le gustaba su función y decidió usarla.
En C, hago todo - funciones y variables - estático en el alcance del archivo hasta que pueda demostrar que son necesarios fuera del archivo. Voy a hacer las cosas estáticas dentro de una función si solo esa función las usará y no son demasiado grandes. Básicamente, si la declaración es más grande que el resto de la función, puedo colocar la declaración fuera de la función. Y, por supuesto, hay un encabezado para los servicios públicos proporcionados por un archivo fuente.
uno debe tener cuidado con la estática en las funciones, en lo que respecta a reentrada y multihilo. – Ilya
@Ilya: de acuerdo. Intento hacer las cosas const también cuando sea posible. Sucede que la mayor parte de mi trabajo no implica enhebrar. Sin embargo, trato de evitar las variables globales; También trato de evitar las variables estáticas, tanto en el alcance del archivo como de la función, donde puedo. –
En el código C, establezca sus funciones estáticas de forma predeterminada.Solo realice funciones no estáticas y declaraciones .h para las funciones que necesitarán otros módulos.
En el código C++, coloque las funciones que son locales al archivo en un espacio de nombre anónimo y para que sean estáticas. En el compilador de GNU al menos, esto dará como resultado el mejor y el más pequeño código, porque no se escribirá ninguna función si todos los usos están en línea. Si pretende que esté en línea, entonces, por supuesto, marcarlo en línea es incluso mejor que la estática.
No sé por qué g ++ escribe los cuerpos de funciones no nombradas que están en espacios de nombres anónimos en el resultado, pero lo hace. Las funciones con visibilidad oculta parecen aparecer también; marcados como símbolos ocultos, pero aún produciendo bloques de código no utilizados en el archivo objeto. GCC probablemente no entiende que el código no es necesario en esos casos. O me estoy perdiendo algo, siempre es posible.
Lo que describió debe haber sido un error de GCC, que no puedo replicar. Si bien esto podría haber sido información útil para las personas que usan ese compilador en ese momento, no tiene sentido extrapolar esto al consejo general de usar ambos 'namespace {' y 'static'. La respuesta correcta es presentar un error, no ensillar el código de otras personas con un texto que no tenga sentido desde el punto de vista del idioma. –
Si está utilizando GCC, entonces debería echar un vistazo a la bandera de visibilidad (vea http://gcc.gnu.org/wiki/Visibility para una discusión completa).
Ocultará los símbolos completamente en lugar de marcarlos inalcanzables. Eso reduce la tabla de símbolos y ayuda a disminuir los tiempos de enlace.
No solo eso, abre la puerta a más líneas internas, si eso es lo que buscas.
En C++, te declaran la función privada así:
class MyClass
{
public:
void publiclyAccessibleFunction();
private:
void onlyAccesibleFromWithinTheClass();
int some_member_parameter;
};
Nota la función onlyAccesibleFromWithinTheClass()
.
OP hablaba de módulos, es decir, archivos fuente compilados por separado y sus encabezados, no objetos. –
De acuerdo. Como consecuencia, los prototipos para las funciones estáticas deben ir en la parte superior del archivo .c, no en el archivo .h.
Eso realmente no evita que se genere el símbolo externo, por lo que podría entrar en conflicto con uno de otro "módulo" –