Один из них определяет макрос таким образом, что в определенных контекстах вхождения идентификатора макроса будут заменены на 0 препроцессором. Другой удаляет любое определение макроса, так что если идентификатор находится в том же контексте, он ничем не заменяется препроцессором, вместо этого он остается как есть.
Например, препроцессор превращает это:
#define MACRO 0
int main()
{
return MACRO;
}
в это:
int main()
{
return 0;
}
Но, это превратит это:
#define MACRO 0
#undef MACRO
int main()
{
return MACRO;
}
в это:
int main()
{
return MACRO;
}
Во втором примере компилятор C встретит идентификатор MACRO
и, вероятно, выдаст ошибку, что он не объявлен, и компиляция, скорее всего, не удастся.