Можем ли мы увидеть код, созданный шаблоном, с помощью компилятора С++

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

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

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

теперь, когда я звоню

add<int>(10,2); 

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

Я использую g++, VС++. Это будет полезно, если некоторые из них могут помочь мне указать параметры компилятора для достижения этого.

Надеюсь, что вопрос ясен. Спасибо заранее.

Ответ 1

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

Я не думаю, что можно отобразить эквивалентный код шаблона "С++", но я все равно хочу, чтобы разработчик 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).

Теперь, как декодировать man-ключ имени С++? есть утилита С++ filt, вы вставляете каноническое (C-эквивалентное) имя и получаете демарнированный эквивалент С++

[email protected] /dev/shm $ c++filt 
_Z3addIiET_S0_S0_ 
int add<int>(int, int)

Ответ 2

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

g++ -S file.cpp

Если вы хотите увидеть некоторый (псевдо) код С++, который генерирует 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;

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

Ответ 3

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); 
}

Command to pretty-print 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);
}

Ответ 4

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

Ответ 5

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

Ответ 6

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