Определить статический порядок инициализации после компиляции?

while, который ничего не делает, вероятно , плохая вещь:

while(!ready) {
   /* Wait for some other thread to set ready */
}

... действительно, действительно, дорогой способ ожидать - он будет использовать столько ЦП, сколько ОС даст его, столько, сколько ready является ложным, крадя процессорное время, с которым другой поток мог делать полезную работу.

Однако Ваш цикл не выполнение ничего:

while ((c = getchar()) == ' ')
    {};  // skip

..., потому что это звонит getchar() на каждом повторении. Следовательно, как все остальные согласились, что Вы сделали, прекрасен.

11
задан Tyler McHenry 3 August 2009 в 20:12
поделиться

5 ответов

Мэтью Уилсон предоставляет способ ответить на этот вопрос в этого раздела (требуется подписка на Интернет-книгу Safari) в Imperfect C ++ . (Хорошая книга, между прочим.) Подводя итог, он создает заголовок CUTrace.h , который создает статический экземпляр класса, который печатает имя файла включаемого исходного файла (используя нестандартный макрос препроцессора ] __ BASE_FILE __ ) при создании он включает CUTrace.h в каждый исходный файл.

Это требует перекомпиляции, но #include «CUTrace.h» можно легко добавить и удалить через сценарий, поэтому его не составит труда настроить.

7
ответ дан 3 December 2019 в 05:35
поделиться

В G ++ в Linux порядок статических конструкторов и деструкторов определяется указателями на функции в секциях .ctors и .dtors. Обратите внимание, что при наличии достаточного количества отладки вы можете получить обратную трассировку:

(gdb) bt
#0  0xb7fe3402 in __kernel_vsyscall ()
#1  0xb7d59680 in *__GI_raise (sig=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0xb7d5cd68 in *__GI_abort () at abort.c:88
#3  0x08048477 in foo::foo() ()
#4  0x0804844e in __static_initialization_and_destruction_0(int, int) ()
#5  0x0804846a in global constructors keyed to foo_inst ()
#6  0x0804850d in __do_global_ctors_aux ()
#7  0x08048318 in _init ()
#8  0x080484a9 in __libc_csu_init ()
#9  0xb7d4470c in __libc_start_main (main=0x8048414 <main>, argc=1,
    ubp_av=0xbfffcbc4, init=0x8048490 <__libc_csu_init>,
    fini=0x8048480 <__libc_csu_fini>, rtld_fini=0xb7ff2820 <_dl_fini>,
    stack_end=0xbfffcbbc) at libc-start.c:181
#10 0x08048381 in _start () at ../sysdeps/i386/elf/start.S:119

Это с установленными отладочными символами для libc и libstdc ++. Как видите, сбой здесь произошел в конструкторе foo :: foo () для статического объекта foo_inst.

Если вы хотите прервать процесс инициализации, вы можете затем установить точку останова на __do_global_ctors_aux и выполнить его разборку , Я полагаю. Или просто подождите, пока произойдет сбой, чтобы получить трассировку, как показано выше.

11
ответ дан 3 December 2019 в 05:35
поделиться

Не могли бы вы инициализировать фиктивные переменные в статическом пространстве и поставить точки останова на эти вызовы функций?

extern "C" int breakOnMe () { return 0 };

int break1 = breakOnMe ();
float pi = 3.1415;
int break2 = breakOnMe ();
myClass x = myClass (1, 2, 3);

Затем в gdb запустите break breakOnMe перед выполнением программы. Это должно заставить gdb останавливаться перед каждой статической инициализацией.

Я думаю, что это должно сработать ... Я немного устарел на gdbbing.

2
ответ дан 3 December 2019 в 05:35
поделиться

Вы можете найти порядок инициализации TU, используя шаблоны, как указано в этом вопросе . Это требует небольшого изменения кода для каждого интересующего вас TU:

// order.h
//

#ifndef INCLUDED_ORDER
#define INCLUDED_ORDER

#include <iostream>

inline int showCountAndFile (const char * file)
{
  static int cnt = 0;
  std::cout << file << ": " << cnt << std::endl;
  ++cnt;
  return cnt;
}

template <int & i>
class A {
  static int j;
};

template <int & i>
int A<i>::j = showCountAndFile (SRC_FILE);

namespace
{
  int dummyGlobal;
}
template class A<dummyGlobal>;

#endif

Основная идея заключается в том, что каждый TU будет иметь свой уникальный адрес для dummyGlobal, и поэтому шаблон будет иметь разные экземпляры в каждом TU. . Инициализация статического члена приводит к вызову «showCountAndFile», который затем распечатывает SRC_FILE (установленный в TU) и текущее значение cnt , которое, таким образом, показывает порядок.

используйте его следующим образом:

static const char * SRC_FILE=__FILE__;
#include "order.h"

int main ()
{
}
1
ответ дан 3 December 2019 в 05:35
поделиться

g ++ предоставляет некоторую помощь в этом.
Это не переносимо, но я уверен, что на данный момент это не ваша основная проблема.

http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes

0
ответ дан 3 December 2019 в 05:35
поделиться
Другие вопросы по тегам:

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