Можем ли мы увидеть шаблон экземпляра кода с помощью компилятора C ++ - PullRequest
38 голосов
/ 15 декабря 2010

есть ли способ узнать экземпляр кода, созданного компилятором, для функции шаблона или класса в C ++

Предположим, у меня есть следующий фрагмент кода

template < class T> T add(T a, T b){
            return a+b;
}

сейчас, когда я звоню

add<int>(10,2); 

Я хотел бы знать, какую функцию создает компилятор для конкретной версии int.

Я использую G ++, VC ++. Будет полезно, если некоторые из них помогут мне указать параметры компилятора для достижения этой цели.

Надеюсь, вопрос ясен. Заранее спасибо.

Ответы [ 6 ]

31 голосов
/ 15 декабря 2010

Если вы хотите увидеть выходные данные сборки, используйте это:

g++ -S file.cpp

Если вы хотите увидеть некоторый (псевдо) код C ++, который генерирует GCC, вы можете использовать это:

g++ -fdump-tree-original file.cpp

Для вашей функции add это будет выводить что-то вроде

;; Function T add(const T&, const T&) [with T = int] (null)
;; enabled by -tree-original

return <retval> = (int) *l + (int) *r;

(я передал параметры по ссылке, чтобы сделать вывод немного более интересным)

28 голосов
/ 04 октября 2017

Clang (https://clang.llvm.org/) может красиво печатать AST экземпляра шаблона:

Например:

test.cpp

template < class T> T add(T a, T b){
    return a+b;
}

void tmp() {
    add<int>(10,2); 
}

Команда для красивой печати AST:

$ clang++ -Xclang -ast-print -fsyntax-only test.cpp

Вывод Clang-5.0:

template <class T> T add(T a, T b) {
    return a + b;
}
template<> int add<int>(int a, int b) {
    return a + b;
}
void tmp() {
    add<int>(10, 2);
}
20 голосов
/ 15 декабря 2010

Вы определенно можете увидеть код сборки, сгенерированный g ++, используя опцию "-S".

Я не думаю, что можно отобразить эквивалентный шаблонный код "C ++" - но я все же хотел бы, чтобы разработчик g ++ отвечал почему - я не знаю архитектуру gcc.

При использовании ассемблера вы можете просмотреть полученный код на предмет того, что напоминает вашу функцию.В результате выполнения gcc -S -O1 {yourcode.cpp} я получил это (AMD64, gcc 4.4.4)

_Z3addIiET_S0_S0_:
.LFB2:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    leal    (%rsi,%rdi), %eax
    ret
    .cfi_endproc

, что на самом деле является просто добавлением int (leal).

Теперь, как расшифровать манипулятор имен c ++?есть утилита под названием c ++ filter, вы вставляете каноническое (C-эквивалентное) имя и получаете расколотый эквивалент c ++

qdot@nightfly /dev/shm $ c++filt 
_Z3addIiET_S0_S0_ 
int add<int>(int, int)
3 голосов
/ 15 декабря 2010

Проще всего проверить созданную сборку.Вы можете получить источник сборки, используя флаг -S для g ++.

2 голосов
/ 15 декабря 2010

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

1 голос
/ 15 декабря 2010

Если вы ищете эквивалентный код C ++, то нет.Компилятор никогда не генерирует это.Компилятору гораздо быстрее сгенерировать промежуточное представление, чем сначала создать c ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...