¿Qué es 'static' en C?

Una sinopsis breve del cualificador static

El cualificador 'static' en C es un tanto misterioso. Dependiendo del lugar en donde nos lo encontremos significa cosas distintas y es preciso conocer su funcionamiento para entender muchos programas escritos en este lenguaje.

El programa que se ofrece a continuación fue escrito hace tiempo con el fin, no de ejecutarlo, sino de mostrar la semántica del cualificador 'static'.

/* Cualificador 'static' en C y C++ */

#include <stdio.h>

/*
 * Todo esto es la teoria, en la realidad hay sutilezas, pero a nivel practico
 * esas sutilezas no importan. Notese que este documento no es preciso ni
 * pretende serlo.
 */

/*
 * definicion.
 * 	bloque:	llamamos bloque a un espacio delimitado por '{' y '}', un bloque
 * 		dentro de otro tiene acceso a los elementos del bloque que esta
 * 		por encima. Luego en el siguiente caso:
 */
void
foo(void) /* void significa que la funcion no toma argumentos */
{ /* comienzo de bloque (1) */
	int a = 1, b = 2;

	{ /* comienzo de bloque (2) */
		int c;

		/* esto es valido, dado que 'c' se encuentra en este bloque */
		c = a + b;

		/*
		 * pregunta: en que nivel de bloque no encontramos ahora?
		 * respuesta: 2
		 */

		{ /* comienzo de bloque (3) */
			int a;
			a = 10;
		} /* fin de bloque (3) */

		/* a pesar de haber asignado la 'a' anteriormente,
                 * ahora tendra el valor inicial de 1, porque una variable es
                 * siempre local a su bloque.
                 * Utilizar este hecho es mala practica, dado que se vuelve muy
                 * ambiguo el alcance de la asignacion de una variable. El
                 * compilador no se confunde, pero tu si.
		 */
	} /* fin de bloque (2) */

	/* si descomentamos la siguiente linea obtenemos un error de
	 * compilacion, donde se quejara de que 'c' no esta declarado en este
	 * bloque, puesto que desde este bloque no podemos ver lo declarado
         * en bloques superiores.
	 */
	/* c = a + b; */

} /* fin de bloque (1) */

/*
 * El bloque se denomina scope en ingles.
 * El bloque global es el que se encuentra fuera de cualquier bloque delimitado
 * por '{' '}', luego es como si fuera accesible por todos los bloques que
 * existen. La siguiente variable se encuentra en un bloque global:
 */
int variable_global = 0;

/* En el bloque global, static significa que el objeto es local al archivo en
 * cuestion, luego otros archivos no pueden verlo ni modificarlo.
 * En un bloque delimitado por '{' '}' el efecto es que el valor se mantiene
 * entre entradas y salidas al bloque, i.e. multiples llamadas a una funcion.
 */

/*
 * Esta variable se inicializa al principio y se puede acceder a ella desde
 * cualquier parte de este archivo a partir de la declaracion.
 */
static int variable_estatica = 10;

int
bar(void)
{
	static int y = 111;
	/* En este caso, 'y' se inicializa la primera vez a 111,
         * sucesivas llamadas a la funcion imprimiran, al guardarse
         * el valor al final del bloque.
	 * 111
         * 112
         * 113
         * ...
         */

	printf("=> %d\n", y); /* En C++: std::cout << y << std::endl; */
	++y;

	/* el valor que devolvemos no tiene bloque asociado, ya que es un rval,
         * o right-value, que es simplemente un valor, no una variable.
         * Unicamente las variables pueden pertenecer a un bloque, ya que los
         * valores no necesitan bloque.
         */
	return y;
}

int
main(int argc, const char **argv)
{
	/* 'argc' y 'argv' se encuentran dentro de este bloque, solo que
         * el valor viene determinado por el invocante */
	int i, j = 0;

	for (i = 0; i < 10; ++i) {
		j += bar();
	}

	printf("j -> %d\n", j);

	return 0;
}

/*
 * Apunte final
 * static es lo que se denomina un cualificador. No es un tipo, solo modifica
 * el tipo de declaracion, similar a como 'const' not cambia la naturaleza de
 * la variable sino su forma de acceso, en la cual se prohibe la escritura de
 * manera conceptual.
 */
Izan, 30 Mar 2026, LLU blog