Макросы в C++
Макросы в C они очень важны, но в C++ применяются гораздо
меньше. Первое правило относительно них такое: не используйте их, если вы не
обязаны это делать. Как было замечено, почти каждый макрос проявляет свой изъян
или в языке, или в программе. Если вы хотите использовать макросы, прочитайте,
пожалуйста, вначале очень внимательно руководство по вашей реализации C
препроцессора.
Простой макрос определяется так:
#define name rest of line
Когда name встречается как лексема, оно заменяется на
rest of line.
Например:
named = name
после расширения даст:
named = rest of line
Можно также определить макрос с параметрами.
Например:
#define mac(a,b) argument1: a argument2: b
При использовании mac должно даваться две строки
параметра. После расширения mac() они заменяют a и b.
Например:
expanded = mac(foo bar, yuk yuk)
после расширения даст
expanded = argument1: foo bar argument2: yuk yuk
Макросы обрабатывают строки и о синтаксисе C++ знают
очень мало, а о типах C++ или областях видимости - ничего. Компилятор видит
только расширенную форму макроса, поэтому ошибка в макросе диагностируется
когда макрос расширен, а не когда он определен. В результате этого возникают
непонятные сообщения об ошибках.
Вот такими макросы могут быть вполне:
#define Case break;case
#define nl
#define forever for(;;)
#define MIN(a,b) (((a)
Вот совершенно ненужные макросы:
#define PI 3.141593
#define BEGIN {
#define END }
А вот примеры опасных макросов:
#define SQUARE(a) a*a
#define INCR_xx (xx)++
#define DISP = 4
Чтобы увидеть, чем они опасны, попробуйте провести
расширения в следующем примере:
int xx = 0;
// глобальный счетчик
void f() {
int xx = 0; // локальная переменная
xx = SQUARE(xx+2); // xx = xx+2*xx+2
INCR_xx; // увеличивает локальный xx
if (a-DISP==b)
{ // a-= 4==b
// ...
}
}
Если вы вынуждены использовать макрос, при ссылке на
глобальные имена используйте операцию разрешения области видимости :: и заключайте вхождения имени параметра макроса
в скобки везде, где это возможно (см. MIN выше).
Обратите внимание на различие результатов расширения этих
двух макросов:
#define m1(a) something(a) // глубокомысленный
комментарий
#define m2(a) something(a) /* глубокомысленный
комментарий */
например,
int a = m1(1)+2;
int b = m2(1)+2;
pасширяется в
int a = something(1) // глубокомысленный комментарий+2;
int b = something(1) /* глубокомысленный комментарий
*/+2;
С помощью макросов вы можете разработать свой собственный
язык. Скорее всего, для всех остальных он будет непостижим. Кроме того, C
препроцессор - очень простой макропроцессор. Когда вы попытаетесь сделать
что-либо нетривиальное, вы, вероятно, обнаружите, что сделать это либо невозможно,
либо чрезвычайно трудно.
Список литературы
Для подготовки данной работы были использованы материалы
с сайта http://www.realcoding.net