Что это за конструкция языка С++: # (т.е. Hash) integer "path_to_header_or_cpp_file" <integer>?
Я столкнулся с следующим кодом в файле .cpp. Я не понимаю конструкцию или синтаксис, который включает файлы заголовков. Я действительно признаю, что эти файлы заголовков относятся к Android NDK. Но, я думаю, вопрос - это общий вопрос о синтаксисе С++.
Кажется, что они представляют собой команды препроцессора, потому что они начинаются с "#". Но они не являются типичными командами #include, #pragma, #ifndef, #define и т.д. Исходный файл имеет более 1000+ таких случаев, ссылающихся на сотни разных файлов .h,.c,.cpp.
typedef int __time_t;
typedef int __timer_t;
# 116 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/machine/_types.h"
# 41 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/sys/_types.h" 2
# 33 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/stdint.h" 2
# 48 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/stdint.h"
typedef __int8_t int8_t;
typedef __uint8_t uint8_t;
Компилятор (GCC), похоже, не вызывает ошибок, связанных с этими строками. Но я хотел бы понять их цель и функцию. Кто-нибудь может объяснить это?
Ответы
Ответ 1
Это выводится из препроцессора GCC. Эти строки известны как linemarkers. Они имеют синтаксис:
# linenum filename flags
Они интерпретируются как говорящие, что следующая строка взята из строки linenum
из filename
. Они в основном просто помогают вам и компилятору видеть, от каких строк были включены. Флаги предоставляют дополнительную информацию:
-
1
- указывает начало нового файла. -
2
- указывает на возвращение файла (после включения другого файла). -
3
- Это означает, что следующий текст поступает из файла заголовка системы, поэтому некоторые предупреждения должны быть подавлены. -
4
- Это означает, что следующий текст следует рассматривать как обернутый в неявный блок extern "C"
.
Вы можете увидеть этот вывод из предварительной обработки ваших собственных программ, если вы даете флаг -E
в g++.
Ответ 2
Обычно вы увидите строки на выходе препроцессора (т.е. вы обычно не должны видеть их вообще).
Они похожи на стандартную директиву #line
, которая имеет форму:
#line 42
или
#line 42 "foo.c"
который компилятор использует для управления содержимым сообщений об ошибках.
Без слова line
это:
# 42 "foo.c"
технически является не директивой (которая, просто для добавления в удовольствие, является своего рода директивой). Это, по сути, комментарий в отношении стандарта C. По предположению, препроцессор gcc, вероятно, испускает эти, а не директивы #line
, потому что директивы #line
предназначены для ввода в препроцессор.
Препроцессор gcc ссылается на них как на "linemarkers"; они обсуждаются в руководстве cpp. Они рассматриваются как директивы #line
, за исключением того, что они могут принимать дополнительный флаг.
Ответ 3
Препроцессоры обычно вводят эти директивы и используют их для указания строки и имени файла. С++ не определяет значение, но он резервирует использование
# <non-directive>
где-то, что не является одной из нормальных директив. Кажется, что записи компилятора согласились использовать номер строки и имя файла в них в результате предварительной обработки файла. Это использование похоже на все компиляторы, поддерживающие параметр -E
, чтобы указать, что файл должен быть просто обработан.