Почему typeid.name () возвращает странные символы с помощью GCC и как заставить его печатать несвязанные имена?

Почему, когда я запускаю это main.cpp:

#include <iostream>
#include <typeinfo>

using namespace std;

struct Blah {};

int main() {
  cout << typeid(Blah).name() << endl;
  return 0;
}

Скомпилировав его с помощью GCC версии 4.4.4:

g++ main.cpp

Я получаю это:

4Blah

В Visual C ++ 2008 я бы получил:

struct Blah

Есть ли способ заставить его просто печатать Blah или struct Blah?


person sivabudh    schedule 16.12.2010    source источник
comment
возможный дубликат типа переменной печати в C ++   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 18.06.2015
comment
Возможный дубликат Распутывание результата std :: type_info :: name   -  person bain    schedule 21.11.2016


Ответы (7)


Возврат name определяется реализацией: реализация даже не требуется для возврата разных строк для разных типов.

То, что вы получаете от g ++, - это оформленное имя, которое можно "распутать" с помощью _ 2_ команду или _ 3_.

person icecrime    schedule 16.12.2010
comment
конкретно c++filt -t - person Paul Evans; 16.01.2015
comment
Фу. Черт возьми, GCC. - person metamorphosis; 02.04.2016

Возвращаемая строка определяется реализацией.

Что делает gcc, так это возвращает искаженное имя.
Вы можете преобразовать искаженное имя в обычный текст с помощью c ++ filter

> a.out | c++filt
person Martin York    schedule 16.12.2010
comment
И вот пример: предположим, что содержимое stdout равно PFPFiiEiiE, мы можем использовать команду оболочки echo "PFPFiiEiiE" | c++filt, и результат будет int (* (*)(int, int))(int). - person Hustlion; 02.09.2017
comment
Возможно, вам (например, в Ubuntu) также потребуется добавить --types для конечных кодов типа demangle: echo "PFPFiiEiiE" | c++filt --types - person zardosht; 13.06.2020

Есть ли способ заставить его просто распечатать

Blah or struct Blah?

Нет. Результат std::typeinfo::name() не указан. Он может даже возвращать одну и ту же строку для всех типов (или, действительно, пустые строки для всех типов), и реализация все равно будет соответствовать стандарту. Нельзя полагаться на его результат. На самом деле, единственное, в чем я нашел его полезным, - это отладка.

Расскажите, для чего вам это нужно. Часто вместо этого вы используете черты.

person sbi    schedule 16.12.2010
comment
в моей программе я просто хочу записать свое имя структуры в файл журнала. Следуя приведенному выше примеру, я мог бы ввести что-нибудь вроде: LOG("Blah");. Но я хочу учесть возможное изменение имени структуры в будущем, поэтому я пытаюсь сделать: LOG(typeinfo(Blah).name(); - person sivabudh; 17.12.2010
comment
@ ShaChris23: Думаю, тогда вам просто придется жить с не всеми компиляторами, которые делают это одинаково. Однако посмотрите, что испускает библиотека времени выполнения, если вместо blah у вас есть сопоставление строк с векторами списков строк. Это может очень легко превысить любые разумные ограничения на размер файла журнала. - person sbi; 17.12.2010

Как говорили другие, результат здесь определяется реализацией, что означает, что реализация (то есть цепочка инструментов компилятора) может свободно определять ее так, как она хочет, при условии, что она где-то документирует это.

Из стандарта C ++, раздел 18.5.1 / 1 [lib.type.info]:

Класс type_info описывает информацию о типе, созданную реализацией. Объекты этого класса эффективно хранят указатель на имя типа и закодированное значение, подходящее для сравнения двух типов на равенство или порядок сортировки. Имена, правила кодирования и последовательность сортировки для типов не определены и могут различаться в разных программах.

person Adam Rosenfield    schedule 16.12.2010

typeid().name() зависит от реализации. Он может даже возвращать пустую строку для каждого типа. Это было бы не очень полезная реализация, но она была бы действительной.

person Juraj Blaho    schedule 16.12.2010
comment
Нет. Он не может возвращать пустую строку для каждого типа. Способ представления строки определяется приложением, но согласно стандарту C ++ он должен отличаться по типу от других. С пустыми строками этого не сделать. - person Rodrigo Gurgel; 03.03.2017

в 4Blah 4 - это количество букв в названии вашего класса. Например, если имя вашего класса myEmptyClass, он напечатает 12myEmptyClass.

person Pradeep Rohilla    schedule 02.06.2016

Используйте ./a.out | c ++ filter --types для GCC.

Для получения дополнительной информации перейдите по ссылкам ниже.

https://sourceware.org/binutils/docs/binutils/c_002b_002bfilt.html#:%7E:text=The%20c%2B%2Bfilt%201,that%20they%20can%20be%20read.&text=Если%20the%20name%20decodes%20into,%20original%20word%20is%20output.

person Abhinav Ghosh    schedule 09.03.2021