variables globales estáticas y externas en C y C++


Hice 2 proyectos, el primero en C y el segundo en C++, ambos funcionan con el mismo comportamiento.

C proyecto:

Cabecera.h

int varGlobal=7;

Main.c

#include <stdio.h>
#include <stdlib.h>
#include "header.h"

void function(int i)
{
    static int a=0;
    a++;
    int t=i;
    i=varGlobal;
    varGlobal=t;
    printf("Call #%d:\ni=%d\nvarGlobal=%d\n\n",a,i,varGlobal,t);
}

int main() {
    function(4);
    function(6);
    function(12);
    return 0;
}

Proyecto C++:

Cabecera.h

int varGlobal=7;

Main.cpp

#include <iostream>
#include "header.h"
using namespace std;

void function(int i)
{
    static int a=0;
    int t=i;
    a++;
    i=varGlobal;
    varGlobal=t;
    cout<<"Call #"<<a<<":"<<endl<<"i="<<i<<endl<<"varGlobal="<<varGlobal<<endl<<endl; 
}

int main() {
    function(4);
    function(6);
    function(12);
    return 0;
}

He leído que las variables globales son externpor defecto y en C y static por defecto en C++; entonces, ¿por qué funciona el código C++?

Quiero decir int varGlobal = 7; es lo mismo que static int varGlobal=7; y si es estático, entonces solo se puede usar en el archivo que se declaró, ¿verdad?

Author: Trevor Hickey, 2012-06-15

2 answers

Las variables globales no son extern ni static por defecto en C y C++. Cuando declara una variable como static, la está restringiendo al archivo fuente actual. Si la declaras como extern, estás diciendo que la variable existe, pero se declara en otro lugar, y si no la declaras en otro lugar (sin la palabra clave extern) obtendrás un error de enlace (símbolo no encontrado).

Su código se romperá cuando tenga más archivos fuente incluyendo ese encabezado, en el tiempo de enlace tendrá múltiples referencias a varGlobal. Si lo declaras como static, entonces funcionará con múltiples fuentes (es decir, compilará y enlazará), pero cada fuente tendrá su propio varGlobal.

Lo que se puede hacer en C++, que no se puede hacer en C, es declarar la variable como const en el encabezado, así:

const int varGlobal = 7;

E incluir en múltiples fuentes, sin romper cosas en tiempo de enlace. La idea es reemplazar el viejo estilo C #define para constantes.

Si necesita una variable global visible en múltiples fuentes y no const, declararlo como extern en el encabezado, y declararlo de nuevo, esta vez sin la clave externa, en un archivo fuente:

Encabezado incluido por varios archivos:

extern int varGlobal;

En uno de sus archivos fuente:

int varGlobal = 7;
 69
Author: fbafelipe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-01 07:21:04

Cuando #include un encabezado, es exactamente como si pusiera el código en el propio archivo fuente. En ambos casos la variable varGlobal está definida en la fuente por lo que funcionará sin importar cómo se declare.

También como se señaló en los comentarios, las variables de C++ en el ámbito de archivo no son estáticas en el ámbito a pesar de que se asignarán al almacenamiento estático. Si la variable fuera un miembro de la clase, por ejemplo, tendría que ser accesible a otras unidades de compilación en el programa por defecto y los miembros no pertenecientes a la clase no son diferentes.

 6
Author: Mark Ransom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-15 18:02:32