Вопросы об управлении именами в С++
Я пытаюсь изучить и понять манипулирование именами на С++. Вот несколько вопросов:
(1) Из devx
Когда глобальная функция перегружена, сгенерированное искаженное имя для каждой перегруженной версии уникально. К переменным относится также изменение имени. Таким образом, локальная переменная и глобальная переменная с тем же именем, заданным пользователем, по-прежнему получают различные искаженные имена.
Существуют ли другие примеры, использующие управление именами, помимо перегрузок функций и глобальных имен и переменных с одним и тем же именем?
(2) Из Wiki
Потребность возникает там, где язык позволяет именовать разные объекты с одним и тем же идентификатором до тех пор, пока они занимают другое пространство имен (где пространство имен обычно определяется директивой модуля, класса или явного пространства имен).
Я не совсем понимаю, почему манипуляция имени применяется только к случаям, когда идентификаторы принадлежат различным пространствам имен, поскольку функции перегрузки могут находиться в одном пространстве имен, а одноименные глобальные и локальные переменные могут также находиться в одном и том же пространстве, Как это понимать?
Имеются ли переменные с одинаковым именем, но в разных областях, также с помощью mangling?
(3) Имеет ли C название mangling? Если это не так, как это может быть связано с тем случаем, когда одни глобальные и локальные переменные имеют одинаковое имя? C не имеет функций перегрузки, правильно?
Спасибо и приветствую!
Ответы
Ответ 1
C не обрабатывает имя, хотя он предварительно подменяет подчеркивание на имена функций, поэтому printf(3)
на самом деле _printf
в объекте libc.
В С++ история отличается. История этого состоит в том, что первоначально Sroustrup создал "C с классами" или cfront, компилятор, который переведет ранний С++ на C. Затем отдохните инструментов - компилятор и компоновщик C мы бы использовали для создания объектного кода. Это означало, что имена С++ должны были быть переведены на C-имена каким-то образом. Это именно то, что делает name mangling. Он предоставляет уникальное имя для каждого члена класса и функции глобального пространства имен и переменных, поэтому имена имен имен и классов (для разрешения) и типы аргументов (для перегрузки) каким-то образом включены в конечные имена компоновщика.
Это очень легко увидеть с помощью таких инструментов, как nm(1)
- скомпилируйте свой источник С++ и посмотрите на сгенерированные символы. Ниже приведено описание OSX с GCC:
namespace zoom
{
void boom( const std::string& s )
{
throw std::runtime_error( s );
}
}
~$ nm a.out | grep boom
0000000100001873 T __ZN4zoom4boomERKSs
В C и С++ локальные (автоматические) переменные не производят никаких символов, а живут в регистре или в стеке.
Edit:
Локальные переменные не имеют имен в результирующем объектном файле по той простой причине, что линкер не должен знать о них. Так что никакого имени, никакого искажения. Все остальное (на что ссылается линкер) искажается имя на С++.
Ответ 2
Mangling - это просто то, как компилятор поддерживает компоновщик.
В C вы не можете иметь две функции с тем же именем, независимо от того, что. Итак, что написал компоновщик, чтобы предположить: уникальные имена. (У вас могут быть статические функции в разных единицах компиляции, потому что их имена не представляют интерес для компоновщика.)
В С++ вы можете иметь две функции с тем же именем, если они имеют разные типы параметров. Таким образом, С++ сочетает имя функции с типами в некотором роде. Таким образом, компоновщик видит в них разные имена.
Обратите внимание, что не имеет значения, как имя искажается, и на самом деле каждый компилятор делает это по-другому. Все, что имеет значение, состоит в том, что каждая функция с тем же базовым именем каким-то образом становится уникальной для компоновщика.
Теперь вы можете видеть, что добавление пространств имен и шаблонов в микс продолжает расширять принцип.
Ответ 3
Технически, он "украшает". Это звучит менее грубо, но из-за того, что CreditInterest
может быть перестроено в IntCrederestit
, тогда как то, что на самом деле происходит, больше похоже на [email protected]
, что, справедливо сказать, "украшено" более чем искаженным. Тем не менее, я называю это искалечением тоже:-), но вы найдете больше технической информации и примеров, если вы ищете "С++ name decoration".
Ответ 4
Существуют ли другие примеры, которые используют управление именами, помимо перегрузок функций и глобальных имен и глобальных имен?
С++ всегда управляет всеми символами. Это проще для компилятора. Как правило, манипуляция кодирует что-то о списке параметров или типах, поскольку они являются наиболее распространенными причинами, требующими манипулирования.
C не мешает. Scoping используется для управления доступом к локальным и глобальным переменным с тем же именем.
Ответ 5
Источник: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
Обработка имени - это процесс, используемый компиляторами С++, дает каждой функции в вашей программе уникальное имя. В С++ обычно программы имеют по меньшей мере несколько функций с тем же именем. Таким образом, определение имени может рассматриваться как важный аспект в С++.
Пример: Обычно имена участников генерируются уникально путем объединения имени элемента с именем класса, например. с учетом декларации:
class Class1
{
public:
int val;
...
};
val становится чем-то вроде:
// a possible member name mangling
val__11Class1