Как работает внутренняя компоновка и почему я получаю одинаковое значение для двух объектов?

#c #internal-link

#c #внутренняя ссылка

Вопрос:

Я пытаюсь понять внутренние ссылки и внешние ссылки, поэтому я попробовал эту программу:

 // foo.h
static int x = 7; // makes x internally linked
void print();

// foo.cpp
#include "bar.h"
#include <iostream>

void func()
{
    std::cout << x << 'n';
}

// bar.h
static int x = 5; // internally linked. without "static" itis linked externally
void func();

// bar.cpp
#include "bar.h"
#include <iostream>

void func()
{
    std::cout << x << 'n';
}

// driver program
    #include <iostream>

// forward declarations
void func();
void print();


int main()
{
    func();
    print();
}
 
  • Я удалил защиту включения (или #pagma один раз) для краткости. Я также переадресовываю объявления func() и print() функции, потому что, если я включу заголовки, в которых они определены foo.h , bar.h компилятор не будет компилироваться из-за переопределения объекта x .
  • Когда я запускаю программу , я всегда получаю одно и то же значение от двух функций func , и print хотя они ссылаются на отдельный объект x .

Вывод:

 5
5
 

Обычно print печатается 7 , потому что включает foo.h в себя то , для чего инициализируется его x объект 7 .

  • Я объявил x в обоих заголовках, static что они должны быть связаны внутри TU, в противном случае, если удалить static из них, то два объекта имеют внешнюю компоновку, что приводит к сбою компоновщика из-за нескольких определений объекта x .

Комментарии:

1. Я думаю, у вас ошибка в опубликованном коде: оба foo.cpp и bar.cpp have func и print нигде не определен, только объявлен. Вы имели в виду для foo.cpp или bar.cpp иметь print функцию вместо func ?

2. Если две подпрограммы также будут выводить amp;x адрес x , вы заметите, что они находятся по разным адресам.

3. Похоже, что оба ваших .cpp файла содержат bar.h . foo.h никогда не компилируется. Итак, ваш вопрос …?

4. Попробуйте переименовать копии func и print в func1 и func2 и print1 и print2 и посмотреть, что произойдет.

Ответ №1:

Я пробовал ваш код, но с foo.cpp as

 #include "foo.h"
#include <iostream>

void print()
{
    std::cout << x << 'n';
}
 

и результат

 5
7
 

как вы и ожидали, поэтому я думаю, что у вас опечатка foo.cpp .