Почему деструктор не называют на исключении?

Следующий новый NewBladeCompiler будет использовать @{ }} для принятия всех php-кодов, таких как назначение переменной, объявление класса и т. д., например. @{ $variable = 0; }} будет скомпилирован в <?php $variable=0; ?>

    <?php

use Illuminate\View\Compilers\BladeCompiler;

class NewBladeCompiler extends BladeCompiler
{

    /**
     * Get the echo methods in the proper order for compilation.
     *
     * @return array
     */
    function getEchoMethods()
    {
        $methods = [
            'compileRawEchos'     => strlen(stripcslashes($this->rawTags[0])),
            'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])),
            'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])),
            'compilePhpEchos'     => strlen(stripcslashes("@{"))
        ];

        uksort($methods, function ($method1, $method2) use ($methods) {
            // Ensure the longest tags are processed first
            if( $methods[$method1] > $methods[$method2] )
            {
                return -1;
            }
            if( $methods[$method1] < $methods[$method2] )
            {
                return 1;
            }
            // Otherwise give preference to raw tags (assuming they've overridden)
            if( $method1 === 'compilePhpEchos' )
            {
                return -1;
            }
            if( $method2 === 'compilePhpEchos' )
            {
                return 1;
            }
            if( $method1 === 'compileRawEchos' )
            {
                return -1;
            }
            if( $method2 === 'compileRawEchos' )
            {
                return 1;
            }
            if( $method1 === 'compileEscapedEchos' )
            {
                return -1;
            }
            if( $method2 === 'compileEscapedEchos' )
            {
                return 1;
            }
        });

        return $methods;
    }

    function compilePhpEchos( $value )
    {
        $pattern  = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', "@{", "}}");
        $callback = function ($matches) {
            $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
            return $matches[1] ? substr($matches[0], 1) : '<?php ' . $matches[2] . ' ?>' . $whitespace;
        };
        return preg_replace_callback($pattern, $callback, $value);
    }

}

?>
50
задан Constantin 22 October 2008 в 07:53
поделиться

5 ответов

Деструктор не называют, потому что оконечный () для необработанного исключения назван, прежде чем стек раскручен.

определенные детали того, что говорит спецификация C++, за пределами моего знания, но трассировка отладки с gdb и g ++, кажется, подтверждает это.

Согласно черновой стандарт раздел 15,3 маркеров 9:

9 If no matching handler is found in a program, the function terminate()
  (_except.terminate_)  is  called.  Whether or not the stack is unwound
  before calling terminate() is implementation-defined.
65
ответ дан Greg Rogers 7 November 2019 в 20:57
поделиться

Состояния спецификации языка C++: процесс вызова деструкторов для автоматических объектов, созданных на пути от блока попытки до выражения отсеивания, называют раскручиванием “stack. ” Ваш исходный код не содержит блок попытки, именно поэтому складывает раскручивание, не происходит.

15
ответ дан Alex Che 7 November 2019 в 20:57
поделиться

Я предположил также, что компилятор не генерирует код относительно "a", поскольку на это не ссылаются, но тем не менее, это не правильное поведение, поскольку деструктор делает что-то, что должно быть выполнено.

Так, я попробовал в VS2008/vc9 (+SP1), Отладка и Выпуск, и ~A называют после того, как исключение выдается, выходя f () - который является правильным поведением, если я прав.

Теперь я просто попробовал VS2005/vc8 (+SP1), и это - то же поведение.

я использовал точки останова, чтобы быть уверенным. Я просто сверился с консолью, и у меня есть сообщение "~A" также. Возможно, Вы сделали это неправильно где-то в другом месте?

2
ответ дан Klaim 7 November 2019 в 20:57
поделиться

Извините у меня нет копии стандарта на мне.
я определенно хотел бы категорический ответ на это, таким образом, кто-то с копией стандарта хочет совместно использовать главу и стих на том, что происходит:

От моего оконечного понимания только назван эквивалентностью:

  • механизм обработки исключений не может найти обработчик для вызванной исключительной ситуации.
    следующее более конкретные случаи этого:
    • раскручивание стека During, исключение выходит из деструктора.
    • брошенное выражение, исключение выходит из конструктора.
    • исключение выходит из конструктора/деструктора не локальных помех (т.е. глобальный)
    • , исключение выходит из функции, зарегистрированной в atexit ().
    • исключение выходит основной ()
  • Попытка повторно бросить исключение, когда никакое исключение в настоящее время не распространяет.
  • непредвиденная исключительная ситуация выходит из функции со спецификаторами исключения (через неожиданный)
2
ответ дан Martin York 7 November 2019 в 20:57
поделиться

Во втором примере называют dtor, когда это оставляет попытку {} блоком.

В первом примере, dtor называют, поскольку программа закрывает после отъезда основного () функцию---, которым, возможно, уже был уничтожен суд времени.

1
ответ дан James Curran 7 November 2019 в 20:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: