Какой объектный файл содержит следующую статическую шаблонную переменную-член?

Скажем, у меня есть следующий шаблонный класс со статической функцией-членом, которая сама создает экземпляр статической переменной (которая функционально является статической переменной-членом, которая создается при первом вызове содержащей ее подпрограммы):

template <typename T>
struct foo
{
static int& mystatic()
{
static int value;

return value;
}
};

Если я использую foo<T> в нескольких единицах перевода для некоторых Tв какой объектный файл помещает компилятор foo<T>::mystatic::value? Как это очевидное дублирование / конфликт разрешается во время соединения?

3

Решение

Вы понимаете, что ваша функция mystatic такое функция с внешней связью? Это означает, что один и тот же конфликт существует между несколькими определениями mystatic сделано в разных переводческих единицах. Также без шаблонов может возникнуть точно такая же проблема: обычные inline функции с внешней связью, определенной в заголовочных файлах, могут вызывать один и тот же очевидный конфликт множественных определений (и там же может быть воспроизведена та же проблема с локальной статической переменной).

Чтобы разрешить такие конфликты, все такие символы помечаются компилятором некоторым зависящим от реализации способом. При этом компилятор сообщает компоновщику о том, что эти символы могут по закону определяться несколько раз. Например, одна известная реализация помещает такие символы в отдельный раздел объектного файла (иногда называемый разделом «COMDAT»). Другие реализации могут маркировать такие символы другим способом. Когда компоновщик обнаруживает такие символы в нескольких объектных файлах, вместо сообщения об ошибке множественного определения он выбирает один и только один каждого идентичного символа и использует его на протяжении всей программы. Другие копии каждого такого символа отбрасываются компоновщиком.

Типичным следствием этого подхода является то, что ваша локальная статическая переменная value должен быть включен в качестве внешнего символа в каждый объектный файл, несмотря на тот факт, что он не имеет связи с языковой точки зрения. Название символа обычно состоит из имени функции mystatic и имя переменной value и некоторые другие искажения.

Другими словами, собственно компилятор помещает как определение mystatic и переменная value в все независимые объектные файлы, которые используют функцию-член. Компоновщик позже убедится, что только один mystatic и только один value будет существовать в связанной программе. Вероятно, нет никакого способа определить, какой исходный объектный файл предоставил выжившую копию (если такое различие даже имеет смысл).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]