C ++ 20是否要求将源代码存储在文件中?


106

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

拥有一个可以通过相机扫描手写纸的编译器将是一个符合要求的实现。尽管实际上没有太大意义。

但是,C ++ 20现在使用添加了源位置file_name。现在,这是否意味着源代码应始终存储在文件中?


13
自从C以来一直存在- __FILE__。类source_location仅允许您在函数调用站点上获取它。
StaceyGirl

28
您不能给手写文件提供文件名吗?
Jarod42

8
我认为无论源代码是文件形式还是其他形式,这都是实现细节。如果可以通过stdin向编译器提供源代码,则源可以在数据库中。
Eljay

8
我的示例可能有点过时,但是如果您使用某些即时编译器(例如TCC),则即使您直接从内存中进行编译,也总是可以提供一些人类可读的源名称来进行错误报告,以便进行错误报告。具有“文件名”并不意味着完全存储为文件。
user7860670

2
当然,诸如实现文件之类的文件<iostream> 可能不是文件(如果您明白我的意思),而不是开发人员编写的文件?

Answers:


110

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

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

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

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

std::source_locationC ++ 20中的引入不会改变这种状况。只是有些代码没有明确定义的源位置(或者可能定义明确,但意义不大)。其实,我想说的是定义上的坚持std::source_location使用的文件是有点近视......虽然在公平,它只是一个宏观相当于少的__FILE____LINE__这已经存在C ++(和C)。

@ HBv6指出,如果您__FILE__在标准输入流中使用GCC进行编译时打印了值:

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

运行生成的可执行文件<stdin>

源代码甚至可以来自Internet。

@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. 程序的文本在本文档中以称为源文件的单元形式保存。通过预处理指令#include将源文件以及所有标头(20.5.1.2)和包含的源文件(19.2)以及任何有条件包含(19.1)预处理指令跳过的任何源行,称为翻译单元。

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

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


9
就标准而言,该管道是“源文件”。
melpomene

5
我正在看C标准,它定义了:“程序的文本在此国际标准中以称为源文件,(或预处理文件)的单元形式保存。” 因此,无论代码存储在哪里,这都是Standardese中的“源文件”。(附录:在[lex]下的C ++标准中可以找到类似的语言。)
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中对无文件系统实现的支持方面没有发生变化。

该标准并未确切定义“源文件”的含义,因此是否引用文件系统可能取决于解释。如果确实能识别该语言的实现中的“源文件”,则可能适合于实现“产生您刚刚给我的手写便笺”。


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


2
@Yksisarvinen我不完全了解规则“推定”限定的意图,但我认为 :)是为了澄清文件名不需要是绝对的或规范的,而从...的角度来看是相对的编译器就足够了。我可能是错的。
eerorika

4
我只能看到scanner-c++返回“左柜子,第三个抽屉,第四个红色标签的文件夹,第17页”
dmckee ---前主持人小猫,

2
从POSIX的角度来看,FWIW,管道(或任何其他类似文件的东西)是“文件”,因此,在这种意义上,stdin / stdout是“文件”,而不是磁盘文件等。

3
@Yksisarvinen:委员会通常会为那些晦涩的实施可能有充分理由做一些与平常行为相反的事情的情况留出余地。这样,它依赖于编译器编写者来判断他们的客户是否会发现普通行为比某些替代方法有用或更少。此类事情留给实施者判断的事实可能被视为“模棱两可”,但这是有意的,因为优秀的编译器作者将比委员会更了解其客户的需求。
超级猫

1
@dmckee ... 在一间废弃的洗手间里,门上有一个标语,上面写着“当心豹子。”
安德鲁·亨利
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.