static и extern глобальные переменные в C и C++

Я сделал 2 проекта, первый в C и второй в C++, оба работают с одинаковым поведением.

C проект:

заголовок.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=%dnvarGlobal=%dnn",a,i,varGlobal,t);
}

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

проект C++:

заголовок.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;
}

Я читал, что глобальные переменные extern по умолчанию и в C и static по умолчанию в C++; так почему же код C++ работает?

Я имею в виду int varGlobal=7; это то же самое, что static int varGlobal=7; и если он статический, то его можно использовать только в файле, который он был объявлен, верно?

2 ответов


глобальные переменные не extern, ни static по умолчанию на C и C++. Когда вы объявляете переменную как static, вы ограничиваете его текущим исходным файлом. Если вы объявите это как extern, вы говорите, что переменная существует, но объявлена где-то еще, и если вы не объявили ее в другом месте (без extern ключевое слово) вы получите ошибку ссылки (символ не найден).

ваш код сломается, когда у вас будет больше исходных файлов, включая этот заголовок, на время ссылки у вас будет несколько ссылок на varGlobal. Если вы объявите это как static, тогда он будет работать с несколькими источниками (я имею в виду, он будет компилироваться и связываться), но каждый источник будет иметь свой собственный varGlobal.

что вы можете сделать в C++, что вы не можете в C, это объявить переменную как const на заголовке, вот так:

const int varGlobal = 7;

и включить в нескольких источниках, не нарушая вещи во время ссылки. Идея состоит в том, чтобы заменить старый стиль C #define для константы.

Если вам нужна глобальная переменная, видимая на нескольких источниках, а не const, объявить его как extern в заголовке и объявите его снова, на этот раз без внешнего ключа, в исходном файле:

заголовок, включенный несколькими файлами:

extern int varGlobal;

в одном из исходных файлов:

int varGlobal = 7;

когда вы #include заголовок, это точно так же, как если бы вы поместили код в исходный файл. В обоих случаях varGlobal переменная определена в источнике, поэтому она будет работать независимо от того, как она объявлена.

кроме того, как указано в комментариях, переменные C++ в области файлов не являются статическими, даже если они будут назначены статическому хранилищу. Например, если переменная является членом класса, она должна быть доступна для других единиц компиляции в программе с помощью члены default и non-class ничем не отличаются.