Как проверить, была ли вызвана основная функция? - PullRequest
0 голосов
/ 05 июня 2011

Я хочу написать некоторый код, который будет зависеть от значения статической переменной.Поэтому я хочу добавить некоторую проверку, чтобы исключить возможность вызова этого кода из других конструкторов статических переменных.И предотвратит статический порядок инициализации фиаско раз и навсегда.Например:

static Foo foo = Foo();

// this function should be called ONLY from main program conrol flow
// ONLY after all static variable initialization was complete! ONLY!
int bar()
{
#ifdef _DEBUG
  if(! CRT_was_initialized_and_main_function_was_called ) ShowErrorMessage();
#endif
  if(foo.somefunction() == 2) return 0; else return -1;
}

//here inattentive programmer will caught error message during debug
const int barConstant = bar();

int main()
{
  //now all is fine
  const int barConstant = bar();
}

Как я могу это сделать?Как проверить, была ли вызвана моя функция после того, как основная функция была?

UPDATE: у объекта Foo очень тяжелый код инициализации, он может быть медленным и даже выдать исключение

UPDATE2: нетжизненное беспокойство, чтобы сделать это.Функция комментариев до бара работала нормально большую часть времени.Я заинтересован в некоторой проверке отладки, чтобы наказать невнимательного программиста в отладочной версии программы вместо того, чтобы делать это вручную.И это может быть нестандартным способом, похожим на вызов какой-то сумасшедшей встроенной функции, которая будет работать только на MSVC.

Ответы [ 5 ]

3 голосов
/ 05 июня 2011

Создать глобальный флаг bool, который указывает, был ли вызван main или нет, изначально false. Измените его на true внутри main() и измените только там. Не элегантное решение, но и решение очень странной проблемы.

0 голосов
/ 05 июня 2011

Не будет ли это хорошим случаем для одноэлементного шаблона, который может проверить свою собственную инициализацию?

0 голосов
/ 05 июня 2011

Вы можете просто объявить глобальную переменную int main_called = 0; перед функцией.

В функции вы проверяете, является ли переменная 0, а в main вы устанавливаете переменную на 1.

0 голосов
/ 05 июня 2011

Нет портативного способа сделать это.Конечно, у вас может быть свой глобальный объект, который вы инициализируете в main, а затем неинициализируете в конце main (не забудьте использовать конструктор / деструктор, чтобы убедиться, что это работает правильно, даже когда исключение выходит из main).

В MSVC более простой, но непереносимый способ - #prgama init_seg.Это дает вам три предустановленных этапа и многие другие, которые вы можете создать сами.

Martyn

0 голосов
/ 05 июня 2011

я бы пошел с этой функцией, а mainCalled - глобальная логическая переменная, которая по умолчанию имеет значение false и заменена на true, когда main вызывается:

int bar()
{
    static bool called = 0;
    if (!mainCalled)
        ShowErrorMessage();
    if (called)
    {
        return -1;
    }
    called = true;
    //do somthing
    return 0;
}
...