Поставьте условие использования «if» в препроцессоре C ++

0

Я написал код в cpp. У меня есть цикл в моем коде, который должен выполняться с определенной частотой. Я хочу, чтобы всякий раз, когда выбранная частота равнялась или превышала 70 Гц, оператор "если" работал, и всякий раз, когда содержимое if выполняется без "if", но я не знаю, как записать его в качестве препроцессора. Я написал что-то вроде этого, но он всегда выполняет "еще" часть этого:

    #define Freq70Hz 70
    int frequency = Freq70Hz;
    int main
    { 
        while(true)
        {
            #if frequency == Freq70Hz 
             if(condition ){
             // do the firstthing
             }
            #else 
            // do the firstthing
            #endif

        }
    }
  • 0
    Не будет ли frequency == Freq70Hz всегда быть правдой?
  • 0
    Почему вы не можете просто сказать, if(frequency == 70) ?
Показать ещё 3 комментария
Теги:
c-preprocessor

4 ответа

3

Здесь вы смешиваете статическое, компилируемое программирование времени с динамическим программированием времени выполнения. В этом случае, как препроцессор знал значение frequency во время компиляции? Это может измениться во время выполнения программы. Вы либо хотите иметь статическое решение, подобное этому:

#define FREQUENCY 70 //this can be changed by passing in compiler options
int main()
{ 
    while(true)
    {
#if FREQUENCY > 70
        if(condition ){
            // do the firstthing
        }
#else 
        // do the firstthing
#endif

    }
}

Или вы хотите динамическое решение, подобное этому:

int frequency = 70;
int main()
{ 
    while(true)
    {
        if(frequency == 70 && condition)
        {
            // do the firstthing
        }
        else
        {
            // do the firstthing
        }
    }
}
  • 0
    Вторым комментарием, вероятно, должно быть «делай второе» каждый раз.
  • 0
    Наверное, так и должно быть, но я оставил это как в своем вопросе ради последовательности.
1

Вы не понимаете, что делает препроцессор.

Препроцессор выполняет текстовую обработку до запуска программы.

В частности, он видит нормальные переменные только как текст и не знает, что их типы или значения будут во время выполнения. Это правда, даже если они являются глобальными переменными, такими как ваша frequency которая инициализируется при запуске программы. Мы видим, что; препроцессор этого не делает.

То, что выглядит как определение псевдонима в #define Freq70Hz 70 - это просто правило замены текста для оставшейся части файла. Текст ("Freq70Hz") будет заменен (на "70") всякий раз, когда он появляется в остальной части программы, но до того, как компилятор увидит код.

Затем вы становитесь жертвой причуды спецификации препроцессора.

Вы считаете, что строка #if frequency == Freq70Hz осмысленно оценивается. Вы надеетесь, что значение переменной frequency, которое мы (но не препроцессор!) Знаем как 70, будет учтено. Но это не то, что происходит.

Препроцессор видит frequency токена препроцессора. Он не имеет понятия, что частота является переменной int, потому что она не может понять язык программирования C. Он видит, что этот токен является частью условного выражения препроцессора. Тем не менее, ему не сказали заменить его значением.

Теперь улов: Идентификаторы, которые все еще существуют после всех замен, были выполнены в условном выражении препроцессора, заменены на 0 (!), Ср. последний проект C n1570, 6.10.1./4. Препроцессор не жалуется на "неопределенные идентификаторы". Это делает директиву #if frequency == Freq70Hz #if 0 == 70, которая, очевидно, всегда ложна.

Поскольку это использование по умолчанию неопределенных идентификаторов препроцессора является опасной особенностью - нормальные языки программирования перестали делать это после Basic - стоит ли знать трюк, который кто-то давно мне показывал: используйте функции макросов. #define Freq70Hz() 70 будет функционально эквивалентным, но жалуются, когда вы опечатаете его позже.

0

Использование устранения мертвого кода с помощью шаблонов

template<bool isGE70Hz>
void DoWhile() {
    while(true) {
        if (isGE70Hz) { // dead code elimination as isGE70Hz is compiletime constant.
            if(condition ){
                // do the firstthing
            } 
        } else {
            // do the firstthing
        }
    }
}

int main() {
    if (frequency >= Freq70Hz) // chose specialization
        DoWhile<true>()
    else
        DoWhile<false>()
    // if frequency and Freq70Hz both are compiletime constants you could do
    // DoWhile<frequency >= Freq70Hz>
}
0

Предполагая, что //do the firstthing SAME в обоих случаях и предполагается, что frequency не будет изменяться в вашем исполнении, я бы не использовал препроцессор для этого... если вы используете static const int frequency = Freq70Hz а затем выполните:

    while(true)
    {
       if(condition || frequency == Freq70Hz){
         // do the firstthing
       }
    }

Компилятор будет компилировать соответствующую вещь, основанную на знаниях о том, что frequency не изменится. То есть, если частота == Freq70Hz, тогда вся часть if не будет в исполняемом файле release. Если частота! = Freq70Hz, тогда часть if будет только условием.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню