2013-06-09 3 views
6

Я никогда не работал с #if, #ifdef, #ifndef, #ELSE, #elif и #endif.Преимущества условно-препроцессора более условных операторов

Поскольку я просматривал некоторые исходные коды, я нашел широкое применение этих директив. Прочитал некоторые условные препроцессоры, но не нашел подсказки, как как они отличаются от обычных условных операторов. Так мне было интересно, что такое преимущество следующего кода:

#include<iostream> 
int main() 
{ 
    int i = 0; 

    #if i == 0 
     std::cout<<"This"; 
    #else 
     std::cout<<"That"; 
    #endif 
    return 0; 
} 

по этому поводу:

#include<iostream> 
int main() 
{ 
    int i = 0; 

    if (i == 0) 
     std::cout<<"This"; 
    else 
     std::cout<<"That"; 
    return 0; 
} 

Кроме того, при использовании/не в использовании условно-препроцессора?

+1

Для начала, 'if' оценивается во время выполнения, а' # if' оценивается до компиляции. – Aiias

+0

http://stackoverflow.com/help/dont-ask – xaxxon

+4

@xaxxon: Вы можете объяснить, как эта ссылка имеет значение? – Blender

ответ

3

Условный препроцессор не работает, как в первом примере.

Он работает с константами, понимаете? Во время компиляции он смотрит на различные условия и помещает/исключает исходный код в соответствии с ним.

Например:

#define HAS_COMPARISON 

int main() { 
    #ifdef HAS_COMPARISON 
     int i = 0; 
     if(i == 0) std::cout << "This"; 
     else 
    #else 
     std::cout << "That"; 
    #endif 
} 

С define набора, он установит переменную i и выполнить сравнение ... Короче говоря, он будет выводить This. Если вы прокомментируете это определение, весь блок не будет в вашей программе, а это значит, что он всегда будет выводить That, не устанавливая переменную или не выполняя сравнение.

Это наиболее распространенное использование препроцессора. Вы также можете определить значения и сравнить их, чтобы иметь поведение переменной с тем же определением, но это еще одна проблема.

Еще раз: условный препроцессор оценивается во время компиляции, переменные условия оцениваются во время выполнения.

+0

~ исправьте меня, если я ошибаюсь, это так, если ** HAS_COMPARISON ** установлен в 0 перед компиляцией, тогда компилятор исключает блок внутри _ # else_ & _ # endif_, как это делает для удаления кода _dead_. – ikis

+0

@iKishore * Препроцессор * отбрасывает код, прежде чем компилятор увидит его, что имеет значение, потому что код, который сделал условным, не может компилировать/вызывать ошибку, когда компилятор видит ее (например, из-за ошибок типа или отсутствующих функций). – delnan

+1

@iKishore Нет, вы правы. Если оно установлено как ЛЮБОЕ значение вообще, '# else' устраняется, а если' # define' удаляется из кода, все от '# ifdef' до' # else' устраняется. –

1

Условная компиляция означает, что код ifdef-ed никогда не находится в последнем связанном приложении. Просто использование языковых условных обозначений означает, что обе ветви находятся в конечном коде, что делает его большим и потенциально труднее тестировать и т. Д.

Используйте #ifdef и т. Д., Когда вы знаете во время компиляции, что требуется. Языковые условия используются, когда вы не знаете, что вам нужно до выполнения.

1

Преимущества препроцессора в том, что код выкидывается. Он не компилируется (требуется время), и он не генерирует машинный код, который будет загружен в ram. Если решение находится в ОЧЕНЬ тугой петле, выполняемой LOTS раз, может быть улучшение скорости. Не думайте, что это важно, если вы на самом деле его не на самом деле.

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

+0

Фактически, если условие является константой времени компиляции (и достаточно простое, чтобы препроцессор был опцией), компилятор обычно может вывести это и удалить мертвый код, если он протестирован с 'if'. – delnan

+0

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

4

Пример, который вы показали, не кажется полезным из-за отсутствия другой информации. Но вот пример, который полезен #if.

#if OS == LINUX 
//do something 
#elif OS == SOLARIS 
//do something else 
#else 
// 
#endif 

Ключ в том, что #if оценивается во время компиляции, но if оценивается при запуске программы.

#if BYTE_ORDER == LITTLE_ENDIAN 
//do something 
#else 
//do something else 
#endif 
2

Использование препроцессоров в этом случае нецелесообразно. Но использование этих препроцессорных директив полезно во многих других случаях.

Эти директивы препроцессора могут использоваться для условной компиляции. например Если какая-то программа должна быть разработана для нескольких платформ, то значениям, зависящим от платформы, могут присваиваться значения. Изменение этих значений компиляции, специфичных для платформы, может быть выполнено, в то время как весь код может поддерживаться как один большой объект.

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

 Смежные вопросы

  • Нет связанных вопросов^_^