результаты typeid не совпадают

У меня есть функция:

 void func(unsigned int event) {
       printf("%u %u\r\n", typeid(event), typeid(unsigned int&));
    // prints 5338164 0
       printf("%u %u\r\n", typeid(event), typeid(unsigned int));
    // prints 21525556 0
}

Предположим, что этот вопрос связан с RTFM, но я несколько раз перечитал справочную страницу typeid() и не нашел ответа. Что не так с этим кодом? Почему %u не равно? также почему он сначала меняет %u, когда я изменил 2-й параметр в коде. Спасибо.


person Sergey Efimov    schedule 30.07.2014    source источник
comment
'\n' уже выполняет \r\n, если система использует окончания строк CRLF. В любом случае, этот код не компилируется в Clang.   -  person chris    schedule 30.07.2014
comment
я предполагаю, что использование \r\n - это хороший стиль и портативный способ   -  person Sergey Efimov    schedule 30.07.2014
comment
typeid(..) возвращает объект типа type_info или что-то производное от него, конечно, не целое число без знака. cppreference: typeid   -  person dyp    schedule 30.07.2014
comment
@SergeyEfimov, если система использует окончания строк CRLF, вы получите \r\r\n. Если он использует окончания строки CR, вы получите \r\r. '\n' — стильный и портативный.   -  person chris    schedule 30.07.2014
comment
@SergeyEfimov: это неправильно. Вы получите ложный \r в любой системе.   -  person Mike Seymour    schedule 30.07.2014
comment
ок, спасибо, не подумал об этом. просто хотел сделать код переносимым, и если я запускаю его в Windows с \n на консоли, он просто идет Y + 1. когда на * nix он переходит к X = 1, Y = Y + 1   -  person Sergey Efimov    schedule 30.07.2014
comment
Ну да, потому что \r возвращается к началу строки.   -  person chris    schedule 30.07.2014


Ответы (2)


Пытаться

printf("%s %s\n", typeid(event).name(), typeid(unsigned int).name());

Как говорилось в предыдущих ответах, результат typeid() непрозрачен и не может быть напечатан, как если бы он был int. Тот факт, что этот код компилируется, является просто результатом плохой типизации C.

person tohava    schedule 30.07.2014
comment
Да, только что посмотрел на эту структуру, я думаю, что возвращаемый тип перегружен. То есть вы имеете в виду, что я не могу получить значение int, описывающее идентификатор типа? Так что единственный способ сравнить строки?? Хм... Или я что-то пропустил? - person Sergey Efimov; 30.07.2014
comment
type_info можно сравнивать, но не печатать, в нем есть == и != - person tohava; 30.07.2014
comment
@SergeyEfimov: Если вам нужно значение int и у вас есть поддержка C++11, используйте typeid(unsigned int).hash_code(). - person Moby Disk; 30.07.2014
comment
@MobyDisk - вы должны сказать ему, что разные типы могут иметь одинаковый хэш_код. Это опасно. - person tohava; 30.07.2014

Итак, typeid возвращает std::type_info не является целым числом без знака. Похоже, что это компилируется в Visual Studio, но неясно, что означает результат. Этот код не компилируется ни в gcc, ни в clang.

Использование неправильного спецификатора формата для printf является неопределенным поведением, поэтому поведение действительно непредсказуемо. Visual Studio не обязана выдавать предупреждение об этом, но это поможет предотвратить подобные проблемы. Поскольку std::type_info не является тривиальным классом, это поведение, определяемое реализацией для использования в вариационной функции, clang выдает это предупреждение:

error: cannot pass non-trivial object of type 'const std::type_info' to variadic function; expected type from format string was 'unsigned int' [-Wnon-pod-varargs]
 printf("%u %u\r\n", typeid(event), typeid(unsigned int));
         ~~  

Использование std::type_info::name, которое возвращает const char даст ожидаемый результат:

 printf("%s %s\n", typeid(event).name(), typeid(unsigned int&).name());

и результат из Visual Studio:

unsigned int unsigned int
unsigned int unsigned int
person Shafik Yaghmour    schedule 30.07.2014
comment
rtti gcc не совместим с ms vc? я имею в виду просто стандартную реализацию С++ rtti на С++ - person Sergey Efimov; 30.07.2014
comment
@SergeyEfimov, похоже, Visual Studio не проверяет типы, которые вы передаете в printf. - person Shafik Yaghmour; 30.07.2014
comment
Интересный! Я не знал, что поведение undefined в C++ stackoverflow.com/questions/10083844 - person Moby Disk; 30.07.2014