Как я могу включить заголовочный файл, который содержит `>` в своем имени?

Это довольно надуманная проблема, я признаю, но вот она.

Предположим, у вас есть файл с символом > в имени. Это возможно в большинстве систем Unix Насколько мне известно:

$ touch 'weird>name'
$ ls -l
-rw-r--r--  1 user  user   0 28 Mag 11:05 weird>name

Теперь предположим, что этот файл содержит код C/C++, и вы хотите включить его в качестве заголовка:

#include <weird>name>

int main() {
  return weird_function();
}

Clang выдает следующую ошибку:

test.cpp:1:10: fatal error: 'weird' file not found
#include <weird>name>

Конечно, так как препроцессор разбирает директиву до первого > и ищет weird файл. Но мне интересно, существует ли какой-то механизм экранирования, позволяющий мне включить правильный файл.

Итак, в C и/или C++ есть ли способ включить заголовочный файл, в имени которого есть символ >?

Редактировать: Многие мне предлагали, почему бы не использовать #include "weird>name". Я признаю, что мой разум ускользнул от синтаксиса кавычек при написании вопроса, но он остается в силе, потому что два синтаксиса могут потребовать от компилятора поиска по разным путям (по крайней мере, теоретически). Итак, есть ли какой-либо механизм экранирования, позволяющий мне включать weird>name с использованием синтаксиса #include <>?

Шаг 1: переименуйте файл. Шаг 2: готово.

Mat 28.05.2019 11:16

Как насчет того, чтобы добавить файл как #include "weird>name"?

Shravan40 28.05.2019 11:17

Да, но это может искать по разным путям. Я уточню.

gigabytes 28.05.2019 11:20

На практике он может искать по одному дополнительному пути, что может быть проблемой только в том случае, если у вас есть файлы с именем weird>name в нескольких местах. Если это правда, вам нужно разобраться с именами файлов и перестать заниматься глупостями :-P Правильный ответ должен быть "какая разница? просто не делайте этого"

Jonathan Wakely 28.05.2019 11:25

"но у них разные пути поиска" - да, '<>': «Целью этого синтаксиса является поиск файлов, находящихся под контролем реализации»., поэтому вам никогда не придется об этом беспокоиться. Если вы включаете пользовательские файлы с помощью «<>», вы делаете это неправильно.

UKMonkey 28.05.2019 11:38

Используя #include "...", если препроцессор не может найти заголовочный файл там, где он ищет, он попытается #include <...> затем, возможно, в другом пространстве поиска.

pmg 28.05.2019 11:40

@pmg Разве это не то, что сказали Shravan40, Джонатан Уэйкли и ОП?

Sneftel 28.05.2019 11:56

@Sneftel: то же самое; это немного более заметно само по себе, даже если в комментарии.

pmg 28.05.2019 12:19

Если вы не можете переименовать файл, создайте символическую ссылку на файл с более подходящим именем.

SKi 28.05.2019 12:58

Аналогичная проблема может возникнуть, если имя файла содержит символы, которых нет в исходном наборе символов (который определяется реализацией). например ?.ч

M.M 28.05.2019 13:31

@eerorika Я не понимаю твоей точки зрения... какое это имеет отношение к намерениям?

UKMonkey 28.05.2019 14:28

Теперь ясно, что продолжение должно включать действительно "странное> имя!

Cort Ammon 29.05.2019 02:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
12
1 331
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

So, in C and/or C++, is there a way to include an header file which has the > character in its name?

Да:

#include "weird>name"

So is there any escaping mechanism to let me include weird>name using the #include <> syntax?

Нет. Символы между < и > должны быть «любыми членами исходного набора символов, кроме новой строки и >» ([lex.заголовок]). Редактирование Любая экранированная форма > по-прежнему будет способом представления символа >, что недопустимо.: реализациям разрешено поддерживать управляющие последовательности, определенные реализацией (см. [lex.header] p2 и его сноску).

Форма #include " q-char-sequence "делает позволяет отображать символ >, даже если он может быть повторно обработан как #include <...>, если поиск как "..." не удался ([cpp.include] p3).

Препроцессор также допускает другую форму ([cpp.include] p4](http://eel.is/c++draft/cpp.include#4)), но ее эффект определяется реализацией, а реализации, которые я пробовал, не позволяют объединять weird, > и name в один токен препроцессора, который затем может быть включенным

Далее: как я могу включить заголовочный файл, который содержит " в своем имени?

Quentin 28.05.2019 11:18

Я признаю, что мой разум ускользнул от синтаксиса "file", но вопрос остается актуальным, хотя и немного менее интересным, потому что <> и "" могут искать по разным путям.

gigabytes 28.05.2019 11:18

@gigabytes Это действительно единственное решение из-за того, как определена грамматика языка! nongnu.org/hcb/#имя-заголовка

BoBTFish 28.05.2019 11:26

@gigabytes — обычно <> означает, что препроцессор ищет в местах, определенных системой (т. е. специфичных для компилятора), а "" означает, что он ищет в местах, определенных пользователем (т. е. которые вы можете указать). Ни один уважающий себя компилятор не будет иметь заголовочный файл с таким именем, как вы описываете, поэтому вы не будете использовать форму <>.

Peter 28.05.2019 11:26

С параметрами компилятора вы можете установить оба пути.

gigabytes 28.05.2019 11:29

Но это, очевидно, не уважающий себя вопрос, поэтому вы можете предположить, что мы не используем уважающий себя компилятор: P

gigabytes 28.05.2019 11:29

@gigabytes «С параметрами компилятора вы можете установить оба пути». Да, но не отдельно. Обычно все пути, которые ищутся для <...>, также ищутся для "...", если первый поиск не удался. Опция GCC -I- позволяет вам это изменить, но она устарела, не соответствует требованиям, не работает и не поддерживается другими компиляторами.

Jonathan Wakely 28.05.2019 11:38

Означает ли это, что файл с именем weird>name" никогда не может быть включен?

Kane 28.05.2019 13:08

Правило состоит в том, что h-char-последовательность не должно быть содержать> (C 2018 6.4.7 1), а не то, что символы в нем не могут быть представлять>. Если бы реализация C определила некоторую последовательность символов в h-char-последовательность, которая представляла бы > в пути к файловой системе, это не нарушило бы стандарт C. Например, #include <weird%3ename> разрешено стандартом C, где %3e представляет >.

Eric Postpischil 28.05.2019 15:10

Я не уверен, что вторая часть правильная. Любая попытка сбежать > на самом деле не будет > персонажем. Тем не менее, препроцессор не обязан распознавать какие-либо управляющие последовательности.

T.C. 28.05.2019 15:11

Да, я изменил этот бит сейчас.

Jonathan Wakely 28.05.2019 15:16

@Kane, посмотрите редактирование ответа - его никогда нельзя включить надежно, но некоторые реализации могут предоставить способ сделать это.

Jonathan Wakely 28.05.2019 15:17

Спросите у автора вашего компилятора.

Стандарты C и C++ предоставляют большую свободу действий при интерпретации директив #include. Нет требования, чтобы #include <foo.h> вызывал включение файла с именем «foo.h». Например, компилятор может выбрать ROT13 для всех имен исходных файлов, если он хочет. А для небуквенно-цифровых символов реализация может идентифицировать и переназначать определенные последовательности символов. Поэтому, если бы была платформа, где > регулярно появлялась в именах файлов, вполне вероятно, что компилятор для этой платформы указал бы, что, скажем, \g или что-то было бы переназначено на >. Но стандарт не предписывает конкретную кодировку.

Кстати, реализация могла бы также просто разрешить #include <weird>name>. Поскольку это не соответствует языковым стандартам, реализация может определять его значение как расширение.

Попробуйте синтаксис ниже:

#include "weird>name"

Другие вопросы по теме