Включенные файлы из стандартных каталогов могут молча заменить существующие макросы? - PullRequest
2 голосов
/ 16 апреля 2019

Создайте файл /usr/local/include/define_x.h в одну строку:

#define X "/usr/local/include"

Следующая программа foo.cpp компилируется и работает без предупреждений:

#include <iostream>

#define X "local"
#include <define_x.h>

int main()
{
  std::cout << "X = " << X << std::endl;
  return 0;
}

Выход: X = /usr/local/include

Теперь поменяйте местами строки 3 и 4:

#include <iostream>

#include <define_x.h>
#define X "local"

int main()
{
  std::cout << "X = " << X << std::endl;
  return 0;
}

Теперь вывод X = local, как и ожидалось, но теперь есть предупреждение компилятора:

foo.cpp:4: warning: "X" redefined
 #define X "local"

In file included from foo.cpp:3:
/usr/local/include/define_x.h:1: note: this is the location of the previous definition
 #define X "/usr/local/include"

Вопрос: Почему в первой версии нет предупреждения?

Оба были скомпилированы с gcc 8.2.1: g++ foo.cpp.

Кажется, это как-то связано с размещением файлов в стандартных каталогах / usr / include или / usr / local / include, так как размещение их либо в текущем каталоге, либо в другом, найденном через -I, не дает такого эффекта .

1 Ответ

1 голос
/ 16 апреля 2019

Системные заголовочные файлы часто не могут быть записаны в строго соответствующем C. Они могут несколько раз изменять некоторые макросы препроцессора, как в этом примере:

#define FOO 0
#ifdef BAR
#define FOO 1
#endif

Было бы неприятно иметь предупреждение за все эти изменения. Поэтому предупреждение не выдается для системных заголовочных файлов.

Ваша строка кода

#include <define_x.h>

объявляет файл заголовка в системный заголовочный файл . Вы должны получить другой результат, если используете

#include "define_x.h"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...