Если вы определяете переменную в файле .cpp, которая должна быть видна только внутри этого файла, вы должны использовать static
.
Если вы хотите разделить значение между двумя lib_base, вам не следует статически связывать его дважды - вы получаете дубликаты как кода, так и данных, что неэффективно и запутанно.
В C ++ есть такая вещь, которая называется правилом единого определения, которая гласит, что вы можете определять одну и ту же вещь столько раз, сколько захотите (так что вы можете включать один и тот же заголовочный файл в несколько файлов cpp), и до тех пор, пока все они определены одинаково , и это будет просто работать. По сути это означает, что компоновщику разрешено выбрасывать дублирующиеся объекты и просто сохранять один случайным образом. Если вы прервете ODR, компилятор не узнает, а компоновщик, вероятно, не узнает, и , тогда , вы получите неопределенное поведение.
В этом случае вы не разбили ODR, но связали одно и то же в два разных объекта (ваше приложение и разделяемую библиотеку), что представляет собой другую проблему. Динамический компоновщик (который загружает разделяемые библиотеки во время выполнения) не беспокоится ни о какой чепухе - все, что он делает, это подключает неопределенные символы в приложении к их определениям в библиотеке. Ваш apName в основном приложении явно не является неопределенным, поэтому динамическому компоновщику там нечего делать, поэтому здесь нет неопределенного поведения.
Если предположить, что вы не хотите, чтобы оба экземпляра lib_base совместно использовали определение aPname, тогда ваше приложение, по-видимому, просто отлично связано (printf доказывает это), но GDB плохо работает с неоднозначными именами символов. Когда GDB ищет имена символов, он не обязательно знает, где искать в первую очередь, поэтому вы не получите то, что ожидали.
Иногда GDB может разобраться в себе, если вы сначала выполните list main
(или что-то еще), чтобы установить желаемый контекст. Хотя, по сути, не дублируйте код - отладчику это не понравится.
Если вы должны это сделать, проверьте команды symbol-table
и add-symbol-table
- вы можете выбрать загрузку только символов из одного или другого файла и отладку нужного вам бита.