Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 408
#1

Почему нельзя подставлять переменные в выражения #if #else? - C++

26.03.2014, 14:25. Просмотров 827. Ответов 27
Метки нет (Все метки)

Почему код работает, не должен же, потому что выражение стоящее после #if вычисляется на этапе компиляции, переменные подставлять нельзя??

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <iostream>
using namespace std;
 
int a = 9;
 
int main(void){
#if a>99
    printf("Kompiliruet, esli a bol'she 9\n");          
#else
    printf("Kompiliruet, esli a men'she 9\n");
#endif
 
    char ch = getchar();
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.03.2014, 14:25     Почему нельзя подставлять переменные в выражения #if #else?
Посмотрите здесь:

Почему в switch нельзя определять переменные? - C++
int main() { setlocale(LC_ALL, &quot;Russian&quot;); int n; std::cout &lt;&lt; &quot;Введите число: &quot;; std::cin &gt;&gt; n; switch...

Почему нельзя использовать в операторе case переменные, которые определены как #define - C++
Я не понимаю, почему Visual Studio ругается на строку с case в коде. Вроде все правильно. Если там написать напрямую цифру, тогда все...

Почему break нельзя использовать в if? - C++
почему break нельзя использовать в if вот код if(f.eof()==1) { break; } про break MVS говорит что ОПЕРАТОР break...

Почему нельзя написать просто - using namespace boost; - C++
Доброго времени суток. В общем, есть программа, в которой я использую тип cpp_int. Вроде его объявление содержится в заголовочном файле...

Почему нельзя выделить статически кусок в ~100 MB? - C++
Есть код #include &lt;iostream&gt; using namespace std; enum { length = 256, count = 50 }; struct Town { char name =...

Почему нельзя так объявить двумерный массив? - C++
Ошибка возникает если для массива tempArray при объявлении(и одновременной инициализации) использовать переменную(size) которую принимает...

Почему таким способом нельзя создать массив? - C++
Хочу создать массив вот таким способом, но выскакивает ошибка error C2057: требуется константное выражение. Ведь у меня и так константа!?...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gelior
26 / 26 / 4
Регистрация: 10.04.2013
Сообщений: 91
26.03.2014, 14:28     Почему нельзя подставлять переменные в выражения #if #else? #2
а, собственно, зачем # перед if и else?
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 408
26.03.2014, 14:31  [ТС]     Почему нельзя подставлять переменные в выражения #if #else? #3
а, собственно, зачем # перед if и else?
смотрю как работает, читаю книгу, там написано то что я написал выше, мне интересно, посему
просто кто то пишет какую то программу, по ходу задает вопросы, а кто то читает книги и примеры "абстрактные"
конечно если я буду писать какую нить программу, я не буду где попало ставить #
Евгений89
99 / 99 / 9
Регистрация: 17.04.2011
Сообщений: 554
Завершенные тесты: 2
26.03.2014, 14:40     Почему нельзя подставлять переменные в выражения #if #else? #4
Директивы #if, #elif, #else и #endif (C/C++)http://msdn.microsoft.com/ru-ru/library/ew2hz0yd.aspx
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 14:41     Почему нельзя подставлять переменные в выражения #if #else? #5
Цитата Сообщение от gelior Посмотреть сообщение
а, собственно, зачем # перед if и else?
Затем, что это макрос условной компиляции.
SatanaXIII
Супер-модератор
Эксперт С++
5594 / 2628 / 240
Регистрация: 01.11.2011
Сообщений: 6,462
Завершенные тесты: 1
26.03.2014, 14:42     Почему нельзя подставлять переменные в выражения #if #else? #6
Zla9_Kolu4ka, зачитайтесь вот из этого источника: Препроцессорные директивы в C/C++ (#include, #define и прочее) .
А именно:
4.2. Директивы #if, #else, #elif, #endif

Синтаксис директивы "#if" очень простой и по большому счёту совпадает с операциями условного исполнения в языке. Как-то особенно на этом останавливаться не буду, просто покажу все варианты использования. Единственное, что нужно отметить - обязательно должен быть "#endif", потому как без него препроцессор не сможет понять, в каком месте заканчивается директива "#if"
C
1
2
3
#if <условие>
...
#endif
C
1
2
3
4
5
#if <условие>
...
#else
...
#endif
C
1
2
3
4
5
6
7
8
9
#if <условие>
...
#elif <условие>
...
#elif <условие>
...
#else
...
#endif
Что касается условия, то хочется ещё раз отметить, что препроцессирование делается отдельно от компиляции, а потому в условии директивы "#if" НЕ могут использоваться никакие переменные из программы. В условии могут использоваться только целочисленные константные значения (которые могут быть значениями других макросов). Над этими константами можно выполнять операции сравнения "==", "!=", "<", "<=", ">", ">=". В условии могут использоваться логические операции "&&", "||", "!", круглые скобки, а так же некая конструкция "defined <macro_name>", значение которой истинно, если макрос <macro_name> определён, в противном случае значение ложно. Препроцессорные "#if'ы", так же, как и языковые, могут быть вложены друг в друга. В строках с директивами можно использовать комментарии
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 14:46     Почему нельзя подставлять переменные в выражения #if #else? #7
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Единственное, что нужно отметить - обязательно должен быть "#endif", потому как без него препроцессор не сможет понять, в каком месте заканчивается директива "#if"
Нет. Второе важное обстоятельство заключается в том, что этот иф обрабатывается статически на этапе компиляции, а условие в нём определяет не поведение программы, а сам её код, то есть от него зависит, что будет в исполняемой версии программы, а чего там вообще не будет.
SatanaXIII
Супер-модератор
Эксперт С++
5594 / 2628 / 240
Регистрация: 01.11.2011
Сообщений: 6,462
Завершенные тесты: 1
26.03.2014, 14:50     Почему нельзя подставлять переменные в выражения #if #else? #8
Цитата Сообщение от taras atavin Посмотреть сообщение
Нет. Второе важное обстоятельство заключается в том, что этот иф обрабатывается статически на этапе компиляции, а условие в нём определяет не поведение программы, а сам её код, то есть от него зависит, что будет в исполняемой версии программы, а чего там вообще не будет.
Нет. Третье, что необходимо отметить, что компиляция вообще не будет возможна при ошибках на этапе препроцессорной обработки, а без нее не имеет смысла говорить о поведении программы, так как код ее не будет сформирован правильно.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 14:54     Почему нельзя подставлять переменные в выражения #if #else? #9
Нет. Этот фактор не отличает от грубых синтаксических ошибок в обычных операторах, если написать, например,
C++
1
if )a>d)
вместо
C++
1
if (a>d)
, или помянуть не существующую переменную, или сравнить величины не сравнимых (для которых нет версии
C++
1
operator >
), то программы тоже не будет. Это общее, а конкретно условная компиляция от условного оператора отличается только двумя факторами.
ValeryS
Модератор
6542 / 5008 / 461
Регистрация: 14.02.2011
Сообщений: 16,655
26.03.2014, 15:06     Почему нельзя подставлять переменные в выражения #if #else? #10
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
Почему код работает, не должен же, потому что выражение стоящее после #if вычисляется на этапе компиляции, переменные подставлять нельзя??
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
int a = 9;
предположу что a сделалась константой
а она известна на этапе компиляции

Добавлено через 2 минуты
попробуй вот так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <iostream>
using namespace std;
 
int a = 9;
 
int main(void){
 
a+=100;
#if a>99
    printf("Kompiliruet, esli a bol'she 9\n");          
#else
    printf("Kompiliruet, esli a men'she 9\n");
#endif
 
    char ch = getchar();
    return 0;
}
что будет?

Добавлено через 1 минуту
Цитата Сообщение от SatanaXIII Посмотреть сообщение
потому в условии директивы "#if" НЕ могут использоваться никакие переменные из программы.
так об чем ТС и спрашивает
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
Почему код работает, не должен же, потому что выражение стоящее после #if вычисляется на этапе компиляции, переменные подставлять нельзя??
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 15:06     Почему нельзя подставлять переменные в выражения #if #else? #11
Цитата Сообщение от ValeryS Посмотреть сообщение
предположу что a сделалась константой
а она известна на этапе компиляции
Константой она не стала, но на этапе компиляции стала известна за счёт инициализации не кодом самой программы, а загрузчиком, входящим в состав операционной системы, то есть не операция присваивания, а само стартовое значение стало частью исполняемого файла. Вот только где гарантия, что подобные тонкости учитывают все компиляторы?
ValeryS
Модератор
6542 / 5008 / 461
Регистрация: 14.02.2011
Сообщений: 16,655
26.03.2014, 15:10     Почему нельзя подставлять переменные в выражения #if #else? #12
Цитата Сообщение от taras atavin Посмотреть сообщение
Константой она не стала,
разумеется нет, поскольку нет const
но для препроцессора наверное да, значение то известно, да и не используется больше нигде
(ключевое слово наверное, т.е я ни в чем не уверен)
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только где гарантия, что подобные тонкости учитывают все компиляторы?
об чем и речь
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 15:11     Почему нельзя подставлять переменные в выражения #if #else? #13
Кроме того, сама возможность изменить переменную означает, что делать так всё равно нельзя:
C++
1
2
3
4
5
6
7
int a=20;
a+=200;
#if a<100
std::cout<<"less"<<std::endl;
#enlse
std::cout<<"more"<<std::endl;
#endif
, хотя перед строкой #if a<100 a уже стала равна 220, но на этапе компиляции она равна 20, в результате будет скомпилировано
C++
1
2
3
int a=20;
a+=200;
std::cout<<"less"<<std::endl;
, а должно быть
C++
1
2
3
int a=20;
a+=200;
std::cout<<"more"<<std::endl;
.
SatanaXIII
Супер-модератор
Эксперт С++
5594 / 2628 / 240
Регистрация: 01.11.2011
Сообщений: 6,462
Завершенные тесты: 1
26.03.2014, 15:14     Почему нельзя подставлять переменные в выражения #if #else? #14
Цитата Сообщение от ValeryS Посмотреть сообщение
так об чем ТС и спрашивает
У меня не работает.
Цитата Сообщение от ValeryS Посмотреть сообщение
об чем и речь
ValeryS
Модератор
6542 / 5008 / 461
Регистрация: 14.02.2011
Сообщений: 16,655
26.03.2014, 15:16     Почему нельзя подставлять переменные в выражения #if #else? #15
для чистоты эксперимента надо бы так написать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <iostream>
using namespace std;
 
int a = 9;
#define b a 
int main(void){
#if a>99
    printf("Kompiliruet, esli a bol'she 9\n");          
#else
    printf("Kompiliruet, esli a men'she 9\n");
#endif
   printf ("%d",b);
    char ch = getchar();
    return 0;
}
что препроцессор из a считывает? может там вообще 0
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 15:18     Почему нельзя подставлять переменные в выражения #if #else? #16
Цитата Сообщение от ValeryS Посмотреть сообщение
что препроцессор из a считывает? может там вообще 0
Там 9.
ValeryS
Модератор
6542 / 5008 / 461
Регистрация: 14.02.2011
Сообщений: 16,655
26.03.2014, 15:25     Почему нельзя подставлять переменные в выражения #if #else? #17
Цитата Сообщение от taras atavin Посмотреть сообщение
Там 9.
я лично не уверен
препроцессор работает до компилятора, инициализации то еще не было
тем более что SatanaXIII, не работает, в каждой палатке свои порядки
вот если бы было
C++
1
const int a = 9;
то вопрос другой, по сути это
C++
1
#define a 9
в тонкости реализации не лезу
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 15:28     Почему нельзя подставлять переменные в выражения #if #else? #18
Цитата Сообщение от ValeryS Посмотреть сообщение
препроцессор работает до компилятора, инициализации то еще не было
Препроцессор тоже умеет читать исходник, так что она вполне была. Вот только юзать эту фичу нельзя, она предназначена не для программирования, а для выявления глюкописцев.
ValeryS
Модератор
6542 / 5008 / 461
Регистрация: 14.02.2011
Сообщений: 16,655
26.03.2014, 15:40     Почему нельзя подставлять переменные в выражения #if #else? #19
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только юзать эту фичу нельзя, она предназначена не для программирования, а для выявления глюкописцев.
вот здесь полностью согласен
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.03.2014, 18:38     Почему нельзя подставлять переменные в выражения #if #else?
Еще ссылки по теме:

Почему два char нельзя сравнивать так ==? - C++
Почему два char нельзя сравнивать так ==?

Почему нельзя компилировать отдельный заголовочный файл? - C++
Вообще можно весь код поместить в один .cpp файл. Но, как я понимаю, люди советуют все функции помещать в отдельные заголовочные файлы. А...

Почему нельзя объявить динамический массив глобально - C++
вот код #include &lt;iostream&gt; #include &lt;string&gt; int w = 0; string *s = new string ; using namespace std; int main { ...

Почему нельзя объявить указатель на шаблонную структуру? - C++
template &lt;class T&gt; typedef struct per { T znach; int kol_vo_povt; }* p; int main() { per&lt;int&gt; k; }

Почему нельзя обратиться к адресу с помощью & в массивах? - C++
Почему нельзя обратиться к адресу с помощью &amp; в массивах; Например: #include &lt;iostream&gt; using namespace std; int main(){ ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6924 / 4117 / 942
Регистрация: 30.01.2014
Сообщений: 6,914
26.03.2014, 18:38     Почему нельзя подставлять переменные в выражения #if #else? #20
О чем вообще разговор-то? Препроцессинг это отдельный этап. Он никак не связан с компиляцией. В том плане что препроцессору вообще побоку что там написано с точки зрения языка. Он обрабатывает текст. Любой. Вообще. А директивы - это средство контроля этой обработки. Заменить там, А на Б. Вставить кусок С или кусок Б в зависимости от определенного условия (которое тем же препроцессором и задается).
Поэтому ни о каком родстве вот этих примеров не может быть и речи
C++
1
2
3
const int a = 9;
 
#define a 9
Первый случай, это языковая константа, которая подчиняется всем правилам языка, таким как: область видимости, время жизни, также учитывается ее тип и место определения. А второе это просто правило для автозамены вида "встретил а - подставь 9".
Yandex
Объявления
26.03.2014, 18:38     Почему нельзя подставлять переменные в выражения #if #else?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru