2011-03-10 18 views
8

Quiero tener una función estática que declaro en mi archivo .c antes de definirlo:¿La palabra clave estática en la declaración de la función puede faltar en la definición de la función?

//file a.c version 1 
static int foo(); 
... 
static int foo() 
{ 
... 
} 

Sin embargo, parece que puedo dejar la palabra clave static fuera de la definición de la función y me da ninguna advertencia del compilador ... p.ej

//file a.c version 2 
static int foo(); 
... 
int foo() 
{ 
... 
} 

¿Estoy en lo correcto al asumir que estas dos formas son exactamente las mismas?
Si es así, ¿por qué se permite esta discrepancia y qué formulario debo usar?

+0

Creo que él/ella está haciendo ejercicio, no escribir un programa real grande. Mi opinión, primera pregunta de tipo de google porque es muy trivial. –

+1

@fatai: es bastante difícil google esta pregunta. Y los abogados de idiomas aquí le proporcionarán una cita del Estándar. –

+1

¡Muchas gracias Erik y AProgrammer por responder la pregunta! ¿Por qué es deseable poder omitir la palabra clave estática en una futura declaración/definición? Me parece que esto sería confuso sin agregar ningún beneficio. – Arrakis

Respuesta

7

Sí 7.1.1/6

Un nombre declarado en un ámbito espacio de nombres sin almacenamiento de clase-especificador tiene enlazado externo a menos que tenga enlace interno debido a una declaración previa y siempre que no esté declarado const.

Ver también los ejemplos de 7.1.1/7

+0

Eso es exactamente sobre lo que estaba leyendo :) en C++ 0x FCD ha habido un cambio 7.1.1/6 se ha convertido en 7.1.1/7 (para aquellos interesados). La redacción sigue siendo idéntica. –

+0

@Matthieu, hemos publicado ... – AProgrammer

+0

¿dónde encontraste esto? :/ – sami1592

1

estática - en este contexto - solo afecta el alcance, cuando declara una función estática tiene alcance de archivo. Por lo tanto, puede verificar fácilmente si es igual al intentar acceder a la función desde otra fuente.

de esa manera evitamos las discusiones sobre el lenguaje compilador etc.

3

7.1.1/7:

Los vínculos implícitos en las declaraciones sucesivas para una entidad determinada serán de acuerdo. Es decir, dentro de un alcance dado, cada declaración que declare el mismo nombre de objeto o la misma sobrecarga de nombre de una función implicará el mismo enlace .

7.1.1/6: (Gracias Steve - esto también es necesaria para que la respuesta sea clara)

Un nombre declarado en un ámbito espacio de nombres sin almacenamiento de clase-especificador tiene enlace externo a menos que tenga enlace interno debido a una declaración anterior y siempre que no sea declarado const. Los objetos declarados const y no explícitamente declarados extern tienen un enlace interno.

Sí, esos dos son iguales.

Sin embargo, esto no es válido:

int foo(); 

static int foo() { 
    return 0; 
} 
+1

.. y el motivo por el que coinciden en el caso del interrogador es 7.1.1/6: "Un nombre declarado en un ámbito de espacio de nombres sin un especificador de clase de almacenamiento tiene un enlace externo a menos que tenga un enlace interno debido a una declaración anterior". No están de acuerdo en su ejemplo por la misma razón. –

+0

Hubo algo insertado antes, el 7 de n3225 es el 6 de C++ 03. – AProgrammer

0

El atributo estático cambia la visibilidad a la unidad de compilación. Esto permite usar el mismo nombre en diferentes archivos para diferentes propósitos. Deberías usar la estática solo una vez. Si tienes un prototipo, debes hacerlo aquí.

Cuando está solicitando C++ no se debe utilizar espacio de nombres estático, sino anónima para que el symbold privada para la unidad de compilación:

namespace { 
    int foo(); 
} 

void bar() 
{ 
    foo(); 
} 
0

Como comentario, C++ proporciona una alternativa superior a static. También puede utilizar espacio de nombres sin nombre aquí

ejemplo,

namespace 
{ 
    void f() 
    { 
    } 
} 

Vea éstas:

Superiority of unnamed namespace over static?
Why an unnamed namespace is a "superior" alternative to static?

+0

No lo encuentro (tan) superior para las funciones. Permite más declaraciones (classes/typedefs), por lo que usarlo también para funciones y constantes crea una sintaxis uniforme (y elimina algunas sobrecargas de la palabra clave), pero 'static' es más conciso. –

+0

Aunque, por supuesto, podría usar * both * namespace * y * static. – Lundin

+0

La palabra clave 'static' en este contexto se declaró obsoleta en alguna versión de los borradores de C++ 0x. Entonces esa decisión fue revocada y ha sido eliminada. En particular para funciones, algunos compiladores tienen mejores diagnósticos cuando declaran funciones 'estáticas' que cuando usan espacios de nombres sin nombre. De hecho, en algunos compiladores, la palabra clave 'static' sí afecta las decisiones (optimizador) que toma el compilador con respecto a esa función libre particular que no se toman cuando se declara la misma función en un espacio de nombre sin nombre. –

Cuestiones relacionadas