Давайте станем педантичными, потому что существуют различия, которые могут на самом деле влиять на поведение Вашего кода. Большая часть следующего взята из комментариев, сделанных к статья .
"Old New Thing" Иногда, память, возвращенная новым оператором, будет инициализирована, и иногда это не будет в зависимости от того, является ли тип, Вы - newing, POD (простые данные) , или если это - класс, который содержит участников POD и использует сгенерированного компилятором конструктора по умолчанию.
Примите:
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
В C++ 98 компиляторов, следующее должно произойти:
new A
- неопределенное значение new A()
- нуль - инициализируют
new B
- конструкция по умолчанию (B:: m является неинициализированным)
new B()
- конструкция по умолчанию (B:: m является неинициализированным)
new C
- конструкция по умолчанию (C:: m инициализируется нулем)
new C()
- конструкция по умолчанию (C:: m инициализируется нулем) В C++ 03 совместимых компилятора, вещи должны работать как так:
new A
- неопределенное значение new A()
- значение - инициализирует A, который является нулевой инициализацией, так как это - POD.
new B
- значение по умолчанию - инициализирует (оставляет B:: m неинициализированный)
new B()
- значение - инициализирует B, которые обнуляют - инициализирует все поля, так как его значение по умолчанию ctor является компилятором, сгенерированным в противоположность пользовательскому.
new C
- значение по умолчанию - инициализирует C, который называет значение по умолчанию ctor.
new C()
- значение - инициализирует C, который называет значение по умолчанию ctor. Так во всех версиях C++ существует различие между [1 113] и new A()
, потому что A является POD.
И существует различие в поведении между C++ 98 и C++ 03 для случая new B()
.
Это - один из пыльных углов C++, который может свести Вас с ума. При построении объекта иногда Вы хотите/нуждаетесь parens, иногда у Вас абсолютно не может быть их, и иногда он не имеет значения.
Начиная с Erlang 21.0, появился новый официальный способ получения трассировки стека. Необязательное совпадение с шаблоном в выражении try для третьего параметра исключения, которое будет содержать трассировку стека:
try
code_that_fails()
catch
_:_:Stacktrace ->
erlang:display(Stacktrace)
end
Для версий Erlang / OTP 20 и ниже, вам необходимо использовать get_stacktrace / 0 , который позволяет вам получить трассировку стека последнего исключения в вызывающем процессе:
try
code_that_fails()
catch
_:_ ->
erlang:display(erlang:get_stacktrace())
end
Ответ на ваш вопрос:
io:format("Backtrace ~p~n", [erlang:get_stacktrace()])
Текущая функция находится во главе списка. Подробнее читайте в man 3erl erlang
или erlang: get_stacktrace / 0
В вашем примере вам не нужна try
; вы можете просто сделать
result = (catch code_that_fails()).
Если возникает исключение, catch
возвращает кортеж, содержащий код ошибки и трассировку стека .
Обратите внимание, что это обычно считается плохой практикой, поскольку он может маскировать исключения. Подход stacktrace, описанный в другом ответе, почти наверняка вам нужен.
try
является расширением исходной функциональности catch
; если вы его используете, вам необходимо указать предложения для каждого типа исключения, которое вы хотите перехватить, и обработать их соответствующим образом. См. Подробности и наглядные примеры в разделах 6.18 / 6.19 справочного руководства Erlang .