rangos - Colocación de declaración variable en C
tipos de variables en c++ pdf (6)
Agrupar las declaraciones de variables en la parte superior del bloque es un legado probablemente debido a las limitaciones de los antiguos compiladores de C primitivos. Todos los idiomas modernos recomiendan e incluso a veces imponen la declaración de variables locales en el último punto: dónde se inicializan por primera vez. Porque esto elimina el riesgo de usar un valor aleatorio por error. La declaración de separación y la inicialización también le impide usar "const" (o "final") cuando pueda.
Desafortunadamente, C ++ sigue aceptando el antiguo y superior método de declaración de compatibilidad con versiones anteriores con C (una compatibilidad con C se arrastra desde muchos otros ...) Pero C ++ trata de alejarse de ella:
- El diseño de las referencias de C ++ ni siquiera permite dicha agrupación de la parte superior del bloque.
- Si separa la declaración y la inicialización de un objeto local C ++, entonces paga el costo de un constructor adicional para nada. Si el constructor no-arg no existe, entonces ni siquiera puedes separar ambos.
C99 comienza a mover C en esta misma dirección.
Si le preocupa no encontrar dónde se declaran las variables locales, significa que tiene un problema mucho mayor: el bloque adjunto es demasiado largo y debe dividirse.
Durante mucho tiempo pensé que en C, todas las variables tenían que declararse al comienzo de la función. Sé que en C99, las reglas son las mismas que en C ++, pero ¿cuáles son las reglas de colocación de declaraciones variables para C89 / ANSI C?
El siguiente código compila con éxito con gcc -std=c89
y gcc -ansi
:
#include <stdio.h>
int main() {
int i;
for (i = 0; i < 10; i++) {
char c = (i % 95) + 32;
printf("%i: %c/n", i, c);
char *s;
s = "some string";
puts(s);
}
return 0;
}
¿Las declaraciones de c
y s
no deberían causar un error en el modo C89 / ANSI?
Citaré algunas declaraciones del manual para gcc versión 4.7.0 para una explicación clara.
"El compilador puede aceptar varios estándares base, como ''c90'' o ''c ++ 98'', y dialectos GNU de esos estándares, como ''gnu90'' o ''gnu ++ 98''. Al especificar un estándar base, el compilador aceptará todos los programas que sigan ese estándar y aquellos que usen extensiones de GNU que no lo contradigan. Por ejemplo, ''-std = c90'' desactiva ciertas características de GCC que son incompatibles con ISO C90, como las palabras clave asm y typeof, pero no otras extensiones de GNU que no tienen un significado en ISO C90, como omitir el término medio de una expresión?: ".
Creo que el punto clave de su pregunta es por qué gcc no se ajusta a C89 incluso si se utiliza la opción "-std = c89". No sé la versión de tu gcc, pero creo que no habrá una gran diferencia. El desarrollador de gcc nos ha dicho que la opción "-std = c89" solo significa que las extensiones que contradicen C89 están desactivadas. Por lo tanto, no tiene nada que ver con algunas extensiones que no tienen un significado en C89. Y la extensión que no restringe la colocación de la declaración de variables pertenece a las extensiones que no contradicen a C89.
Para ser honesto, todos pensarán que debería ajustarse a C89 totalmente a primera vista de la opción "-std = c89". Pero no es así En cuanto al problema que declara que todas las variables al principio es mejor o peor es solo una cuestión de hábito.
Como señalaron otros, GCC es permisivo a este respecto (y posiblemente otros compiladores, dependiendo de los argumentos con los que están llamados) incluso cuando están en el modo ''C89'', a menos que use la verificación ''pedantic''. Para ser honesto, no hay muchas buenas razones para no tener pedante; el código moderno de calidad siempre debe compilarse sin advertencias (o muy pocas cuando sabe que está haciendo algo específico que es sospechoso para el compilador como un posible error), de modo que si no puede compilar su código con una configuración pedante, probablemente necesite algo de atención.
C89 requiere que las variables sean declaradas antes de cualquier otra declaración dentro de cada alcance, luego las normas permiten una declaración más cercana al uso (que puede ser más intuitiva y más eficiente), especialmente la declaración simultánea y la inicialización de una variable de control de bucle en bucles ''for''.
Desde un punto de vista de mantenimiento, en lugar de sintáctico, hay al menos tres líneas de pensamiento:
Declare todas las variables al principio de la función para que estén en un solo lugar y podrá ver la lista completa de un vistazo.
Declare todas las variables lo más cerca posible del lugar en que se usan por primera vez, para que sepa por qué cada una es necesaria.
Declare todas las variables al principio del bloque de ámbito más interno, por lo que saldrán del alcance lo antes posible y permitirán que el compilador optimice la memoria y le diga si las usa accidentalmente donde no había sido su intención.
Generalmente prefiero la primera opción, ya que los otros a menudo me obligan a buscar el código para las declaraciones. Definir todas las variables por adelantado también hace que sea más fácil inicializarlas y verlas desde un depurador.
A veces declararé variables dentro de un bloque de alcance más pequeño, pero solo por una Buena Razón, de la cual tengo muy pocas. Un ejemplo podría ser después de un fork()
, para declarar las variables necesarias solo por el proceso hijo. Para mí, este indicador visual es un recordatorio útil de su propósito.
Para C89, debe declarar todas sus variables al comienzo de un bloque de alcance .
Entonces, su declaración de charc es válida, ya que está en la parte superior del bloque de ámbito de bucle for. Pero, la declaración de char_s debe ser un error.
Se compila con éxito porque GCC lo permite como una extensión de GNU, aunque no es parte del estándar C89 o ANSI. Si desea adherirse estrictamente a esos estándares, debe pasar el indicador -pedantic
.