#define, #ifdef #undef #endif - PullRequest
       39

#define, #ifdef #undef #endif

2 голосов
/ 26 ноября 2009

У меня есть следующий код

#define PROC_ADD

void main(void)
{
    while(1)
    {
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
    }
}

Однако он запустит код. Но он не будет запускать код в else после того, как PROC_ADD был неопределен.

Я думаю, причина может быть в том, что вы можете определять и отменять определение только во время компиляции, а не во время выполнения. Однако я не совсем уверен.

Ответы [ 6 ]

4 голосов
/ 26 ноября 2009

То, что вы делаете, является эквивалентом времени сборки:

int x = 1;

int main()
{
    if (x)
    {
        ...
        x = 0;
    }
    else
    {
        ...
    }
}

ifdef и т. Д. Происходят во время сборки, но для вашего примера это не проблема. После того, как вы оцените if (либо форму выполнения, либо форму времени сборки), принимается решение о том, какую ветвь принять. Изменение чего-либо после принятия решения не меняет это решение.

3 голосов
/ 26 ноября 2009

Условие ifdef оценивается, когда препроцессор добирается до него. Когда вы undef PROC_ADD внутри кода ifdef ', препроцессор уже решил, какой раздел кода включить, а какой игнорировать.

Кроме того, да: ifdef, undef и т. Д. Обрабатываются во время предварительной обработки - компилятор даже не видит эти так называемые директивы. Это, конечно, означает, что код времени выполнения никогда не видит эти директивы.

Редактировать : Препроцессор работает, выполняя один проход по текстовому файлу. Препроцессору даже не важно, что ваш текстовый файл содержит код C! Он не знает, что ваши ifdef s и else s и что-то еще находятся внутри цикла while.

3 голосов
/ 26 ноября 2009

#define с работают только во время предварительной обработки. Так

#define PROC_ADD 
void main(void) 
{
#ifdef PROC_ADD 
// Do this code here then undefined it to run the code in the else 
// processing work 
#undef PROC_ADD 
#else 
// now that PROC_ADD has been undefined run this code 
// processing work 
#endif 
}

будет обрабатываться следующим образом: поскольку определено PROC_ADDR, препроцессор полностью исключит ветвь #else и затем выполнит #undef, поэтому код ветки #else никогда не переживает предварительную обработку и никогда не достигает компилятора.

2 голосов
/ 26 ноября 2009

Почти во всех языках программирования или синтаксисе, когда выполнение входит в одну ветвь условного выражения (в данном случае условное значение равно #ifdef, даже если условие изменяется во время выполнения ветвления, другие ответвления никогда не будут выполнены .

Я уверен, что вы не ожидаете, что это напечатает "Hello", не так ли?

if (i == 1)
    i = 0;
else
    printf("Hello\n");

По сути, вы говорите, что код в ветви else всегда должен выполняться, затем просто вынуть его из ветви и поместить его непосредственно в код .

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

2 голосов
/ 26 ноября 2009

То есть вы хотите, чтобы код, представленный во втором разделе комментариев, всегда выполнялся? Почему бы просто не сделать

#ifdef PROC_ADD
// Do the stuff to be done if PROC_ADD is defined
#undef PROC_ADD
#endif
// Do the stuff to always be done

редактировать

ОК - если вы хотите изменить поведение во время выполнения, вы должны использовать конструкции во время выполнения (например, переменную, служащую флагом). Как мы все говорим;), директивы препроцессора вычисляются только один раз, во время компиляции.

1 голос
/ 26 ноября 2009

Подумайте об этом следующим образом: else часть следующего кода не выполняется, даже если x было установлено на false в разделе if.

Условие проверяется в самой строке if(x) - когда он входит в этот блок, он не пересчитывает каждый из последующих разделов else - компилятор уже принял решение по этому вопросу.

bool x = true;
if(x)
{
  //do something
  x = false;
}
else
{
  //else code
}
...