Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
template_metaprogramming_ru.docx
Скачиваний:
12
Добавлен:
01.07.2025
Размер:
774 Кб
Скачать
☆

Отладка ошибок

Ошибочным есть «угадывание» истинной причины сообщения об ошибке, путем внесения произвольных изменений в код программы.

Нюанс:

Примеры сообщений об ошибках, явялются неполными и передают только главную суть, т.к. в полном размере эти сообщения занимают много места.

Трассировка инстанцирования

Запустим простой (ошибочный) пример. Следующий код определяет упрощенный связанный список времени компиляции, и метафункцию, разработанную, чтобы вычислить полный размер списк, определяя размер всех его элементов:

struct nil {}; // the end of every list

template <class H, class T = nil> // a list node, e.g: node<X,node<Y,node<Z>>>

struct node

{

typedef H head; typedef T tail;

};

template <class S>

struct total_size

{

typedef typename total_size< // total size of S::tail

typename S::tail

>::type tail_size; // line 17

typedef boost::mpl::int_< // add size of S::head

sizeof(S::head)

+ tail_size::value // line 22

> type;

};

Ошибка: отсутствует специализация для остановки рекурсии.

typedef total_size<

node<long, node<int, node<char>>>

>::type x; // line 27

Сообщение об ошибке (версии 3.2 GNU C ++ компилятор (GCC)):

foo.cpp: In instantiation of 'total_size<nil>':

foo.cpp:17: instantiated from 'total_size<node<char, nil> >'

foo.cpp:17: instantiated from 'total_size<node<int,node<char, nil > > >'

foo.cpp:17: instantiated from 'total_size<node<long int, node<int, node<char, nil> > > >'

foo.cpp:27: instantiated from here

foo.cpp:17: no type named 'tail' in 'struct nil'

continued...

В этих сообщения (дамп ошибок) содержится полезная информация. Эти сообщения являются трассировкой инстанцирования, следы которой почти точно соответствуют трассировке стека вызовов времени выполнения.

Первая строка сообщения об ошибке показывает метавызов функции, в которой произошла ошибка, а каждая последующая строка соответствует вызовам метафункции, которые привели к ошибке, указанной в первой строке.

В конце компилятор показывает низкоуровневую причину ошибки: обращение к последнему элементу списка – nil и попытка доступа к его вложенному элементу «::tail».

В этом примере легко понять где ошибка просто посмотрев последнюю строку дампа (в MSVC10 данная строка следует первой: error C2039: tail: не является членом "nil"), так, ошибка в первых строках может приводить к появлению множества ошибок в строках ниже.

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

Если ошибка не столь проста как недостающая точка с запятой, те предположения имеют тенденцию быть неправильными, что привоит к появлению сообщений о псевдо-ошибках:

...continued from above

foo.cpp:22: no type named 'tail' in 'struct nil'

foo.cpp:22: 'head' is not a member of type 'nil'

foo.cpp: In instantiation of 'total_size<node<char, nil> >':

foo.cpp:17: instantiated from 'total_size<node<int, node<char,nil> > >'

foo.cpp:17: instantiated from 'total_size<node<long int, node<int, node<char, nil> > > >'

foo.cpp:27: instantiated from here

foo.cpp:17: no type named 'type' in 'struct total_size<nil>'

foo.cpp:22: no type named 'type' in 'struct total_size<nil>'

...many lines omitted here...

foo.cpp:27: syntax error before ';'token

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]