Обязан ли C ++ 20 хранить исходный код в файлах?

106

Однако немного странный вопрос, если я правильно помню, исходный код C ++ не требует файловой системы для хранения файлов.

Наличие компилятора, который сканирует рукописные документы через камеру, было бы соответствующей реализацией. Хотя практически не имеет особого смысла.

Однако C ++ 20 теперь добавляет расположение источника с расширением file_name. Означает ли это, что исходный код всегда должен храниться в файле?

JVApen
источник
13
Это всегда было в C - __FILE__. Класс source_locationпросто позволяет вам получить его на сайте вызова функции.
StaceyGirl
28
Разве вы не можете дать имя файла вашим рукописным бумагам?
Jarod42
8
Я думаю, это деталь реализации, находится ли исходный код в файлах или что-то еще. Если компилятору можно передать исходный код через стандартный ввод, источник может находиться в базе данных.
Eljay
8
Мой пример может показаться немного неуместным, но если вы используете какой-нибудь оперативный компилятор, такой как TCC, вы всегда можете указать какое-нибудь удобочитаемое имя источника для сообщения об ошибках, даже если вы компилируете напрямую из памяти. То, что наличие «имени файла» вовсе не означает, что он будет храниться в виде файла.
user7860670
2
Конечно, это файлы реализации, такие как <iostream> эти, могут не быть файлами (если вы понимаете, что я имею в виду), а не файлами, написанными разработчиками?

Ответы:

110

Нет, исходный код не обязательно должен быть из файла (или переходить в файл).

Вы можете скомпилировать (и связать) C ++ полностью внутри канала, поместив свой компилятор посередине, например

generate_source | g++ -o- -xc++ - | do_something_with_the_binary

и так было десятилетиями. Смотрите также:

Введение std::source_locationв C ++ 20 не меняет этого положения вещей. Просто у некоторого кода не будет четко определенного местоположения источника (или оно может быть четко определено, но не очень значимо). На самом деле, я бы сказал , что настаивание на определении с std::source_locationпомощью файлов немного близорук ... хотя справедливости ради, это просто макро-менее эквивалент __FILE__и __LINE__которые уже существуют в C ++ (и C).

@ HBv6 отмечает, что если вы напечатаете значение __FILE__при компиляции с использованием GCC из стандартного входного потока:

echo -e '#include <iostream>\n int main(){std::cout << __FILE__ ;}' | g++ -xc++  -

запуск полученного исполняемого файла печатает <stdin>.

Исходный код может быть получен даже из Интернета.

@Morwenn отмечает, что этот код:

#include <https://raw.githubusercontent.com/Morwenn/poplar-heap/master/poplar.h>

// Type your code here, or load an example.
void poplar_sort(int* data, size_t size) {
    poplar::make_heap(data, data + size);
    poplar::sort_heap(data, data + size);
}

работает на GodBolt (но не будет работать на вашем компьютере - ни один популярный компилятор не поддерживает это.)

Вы языковой юрист? Хорошо, давайте посмотрим на стандарт ..

Вопрос о том, должны ли исходные коды программ C ++ происходить из файлов, не имеет четкого ответа в языковом стандарте. Глядя на черновик стандарта C ++ 17 (n4713), раздел 5.1 [lex.separate] гласит:

  1. Текст программы хранится в единицах, называемых в этом документе исходными файлами. Исходный файл вместе со всеми заголовками (20.5.1.2) и исходными файлами, включенными (19.2) с помощью директивы предварительной обработки #include, за вычетом любых строк исходного кода, пропущенных любой из директив предварительной обработки условного включения (19.1), называется единицей преобразования.

Итак, исходный код не обязательно хранится в файле как таковом, а в «модуле, называемом исходным файлом». Но тогда откуда берутся включения? Можно было бы предположить, что они поступают из именованных файлов в файловой системе ... но это тоже не является обязательным.

В любом случае, std::source_locationпохоже , это не меняет эту формулировку в C ++ 20 или не влияет на ее интерпретацию (AFAICT).

Эйнпоклум
источник
9
Этот канал является «исходным файлом» для целей стандарта.
melpomene
5
Я смотрю на стандарт C, который определяет: «Текст программы хранится в единицах, называемых исходными файлами (или файлами предварительной обработки ) в этом международном стандарте». Итак, где бы ни хранится код, это «исходный файл» на стандартном языке. (Приложение: аналогичный язык можно найти в стандарте C ++ в разделе [lex].)
melpomene
8
@melpomene: единицы просто называются исходными файлами, это не говорит о том, что они действительно должны быть исходными файлами. Но я отредактирую ответ, чтобы включить это.
einpoklum
13
Просто попробовал это с помощью GCC: "echo '#include <stdio.h> \ nint main () {printf ("% s \\ n ", __FILE__); return 1;}' | gcc -o test -xc -" ( без кавычек). При выполнении выводит <stdin>.
HBv6
11
Вот забавная вещь о терминах, именах и концепциях в стандартах (и науках): они обычно атомарны. То есть «исходный файл» не обязательно является «файлом», который является «источником», на самом деле термин «файл» может просто не определяться - сравните с числами в математике: не существует такой вещи, как просто « число », только« натуральное число »,« рациональное число »,« действительное число »и т. д.
Joker_vD
53

Еще до C ++ 20 в стандарте были:

__FILE__

Предполагаемое имя текущего исходного файла (литерал символьной строки).

Определение то же самое для source_location::file_name.

Таким образом, не было изменений в отношении поддержки реализаций без файловой системы в C ++ 20.

Стандарт не совсем точно определяет, что означает «исходный файл», поэтому вопрос о том, относится ли он к файловой системе, зависит от интерпретации. Предположительно, реализация могла бы соответствовать созданию «рукописной заметки, которую вы мне дали только тогда», если она действительно идентифицирует «исходный файл» в этой реализации языка.


В заключение: Да, по стандарту источники называются «файлами», но что такое «файл» и задействована ли файловая система, не определено.

eerorika
источник
2
@Yksisarvinen Я не знаю точно, что подразумевается под "презумпцией" правила, но я предполагаю :) что это пояснение, что имя файла действительно должно быть абсолютным или каноническим, а скорее относительным именем с точки зрения компилятора достаточно. Я могу ошибаться.
eerorika
4
Я только вижу scanner-c++возвращение «Левый шкаф, третий ящик, четвертая папка с красными вкладками, страница 17» .
dmckee --- котенок экс-модератора
2
FWIW, в смысле POSIX, канал (или любая другая файловая вещь) является «файлом» - как таковые, stdin / stdout - это «файлы», а не файлы на диске и т. Д. В этом смысле.
3
@Yksisarvinen: Комитет часто делает поправку на ситуации, когда у непонятных реализаций могут быть веские причины сделать что-то, противоречащее обычному поведению. Поступая таким образом, он полагается на авторов компилятора, чтобы судить, найдут ли их клиенты обычное поведение более или менее полезным, чем какая-либо альтернатива. Тот факт, что такие вещи оставлены на усмотрение разработчиков, можно рассматривать как «двусмысленность», но это сделано умышленно, поскольку хорошие составители компиляторов будут знать о потребностях своих клиентов больше, чем когда-либо мог бы Комитет.
supercat
1
@dmckee ... в заброшенном туалете с табличкой на двери: «Остерегайтесь леопарда».
Эндрю Хенле