109

但是,如果我没记错的话,这是一个有点奇怪的问题,C++ 源代码不需要文件系统来存储其文件。

拥有一个通过相机扫描手写文件的编译器将是一个符合要求的实现。虽然实际上没有那么大的意义。

然而,C++20 现在添加了带有file_name. 现在这是否意味着源代码应该始终存储在文件中?

4

2 回答 2

113

不,源代码不必来自文件(也不必转到文件)。

您可以在管道内完全编译(和链接)C++,将编译器放在中间,例如

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

几十年来一直如此。也可以看看:

C++20 中的引入std::source_location并没有改变这种状况。只是有些代码不会有明确定义的源位置(或者可能定义明确,但意义不大)。实际上,我会说坚持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) 和通过预处理指令 #include 包含的源文件 (19.2),减去由任何条件包含 (19.1) 预处理指令跳过的任何源代码行,称为翻译单元。

因此,源代码本身不一定保存在文件中,而是保存在“称为源文件的单元”中。但是,包含从何而来?有人会假设它们来自文件系统上的命名文件......但这也不是强制性的。

无论如何,std::source_location似乎并没有改变 C++20 中的这个措辞或影响它的解释。

于 2019-08-18T21:30:19.267 回答
53

甚至在 C++20 之前,该标准就有:

__FILE__

当前源文件的假定名称(字符串文字)。

的定义相同source_location::file_name

因此,在 C++20 中对无文件系统实现的支持没有变化。

该标准并未准确定义“源文件”的含义,因此它是否指的是文件系统可能取决于解释。据推测,如果确实标识了该语言实现中的“源文件”,则实现生成“您当时给我的手写笔记”可能是符合要求的。


总结:是的,标准将源称为“文件”,但未指定“文件”是什么以及是否涉及文件系统。

于 2019-08-18T20:48:11.213 回答