#c
Вопрос:
допустим, у нас есть набор вызовов функций, которые выполняются в следующем порядке, аналогичном дереву. то есть func0 вызывает func1 и func2 по порядку. и func2 приводит к вызову func3, после чего func0 переходит к следующей строке для выполнения func4.
func0 // depth 0
func1 // depth 1
func2 // depth 1
func3 // depth 2
func4 // depth 1
func5 // depth 2
func6 // depth 3
func7 // depth 4
func8 // depth 2
func9 // depth 0
Какую строку кода я могу вставить в каждую из этих функций, чтобы напечатать такую глубину?
Комментарии:
1. Один из способов, который я могу придумать, — это передача аргумента каждой функции, который будет указывать глубину. Затем вы просто выводите имя функции в соответствующем формате.
2. boost.org/doc/libs/1_77_0/doc/html/stacktrace.html может помочь в противном случае вам нужно сообщить нам, на какую платформу вы ориентируетесь, поскольку не существует стандартного c api для опроса стека вызовов
3. @AlanBirtles нестандартный фрагмент c также может быть полезен. Я, например, думал, что, используя какую-то глобальную переменную, я мог бы это сделать. моя основная платформа — linux, но я также могу использовать ее в Windows
Ответ №1:
Один из способов — создать класс RAII, который подсчитывает глубину, и создать его экземпляр в верхней части каждой функции, которую вы хотите отслеживать. Я делал подобные вещи для целей отладки.
class DepthCounter
{
static int depth;
public:
DepthCounter(const std::stringamp; name)
{
std::cout << std::string(depth*2, ' ') << name << " // depth " << depth << 'n';
depth;
}
~DepthCounter()
{
--depth;
}
};
int DepthCounter::depth = 0;
Вы можете создать экземпляр этого в каждой функции с помощью чего-то вроде:
DepthCounter dc(__func__);
Вы можете назвать экземпляр как угодно, но без указания имени переменной он будет просто временным и будет уничтожен по существу через точку с запятой. Делая его переменной, он живет до тех пор, пока функция не завершит работу любыми способами, будь то выпадение из конца, явный возврат или исключение.
Я не показал весь код (должен оставить что-то для вас), но результат, который я получил, выглядит так:
func0 // depth 0
func1 // depth 1
func2 // depth 1
func3 // depth 2
func4 // depth 1
func5 // depth 2
func6 // depth 3
func7 // depth 4
func8 // depth 2
func9 // depth 0
Комментарии:
1. Есть ли у вас рекомендации по ее созданию? когда я создаю его как DepthCounter(«счетчик»), но без присвоения его переменной, я думаю, что он уже уничтожает класс, когда переходит к следующей строке кода внутри той же функции
2. Я только что сделал
DepthCounter dc(__func__);
в каждой функции. Не указывая ей имя переменной, вы просто создаете временную, и она уничтожается по существу с запятой. Делая его переменной, он живет до тех пор, пока функция не завершит работу любыми способами, будь то выпадение из конца, явноеreturn
или через исключение.3. можете ли вы предложить способ, которым, если я создам его экземпляр, снова в той же функции, он вернет ту же глубину? потому что на данный момент конструктор всегда добавляет глубину
4. Не создавайте его экземпляр более одного раза в одной и той же функции. Только один раз, первым делом в каждой функции.
5. да, но моя основная цель — на самом деле делать что-то в одной и той же функции несколько раз, например, вести журнал с одинаковым номером глубины, предпочтительно используя также одну строку. например, может ли конструктор получить что-то, что указывает, что он все еще находится в текущей функции, не увеличивать глубину?