【问题标题】:Does C++20 mandate source code being stored in files?C++20 是否要求将源代码存储在文件中?
【发布时间】:2023-04-04 18:32:01
【问题描述】:

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

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

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

【问题讨论】:

  • 这一直在 C 中 - __FILE__source_location 类只允许您在函数调用站点获取它。
  • 你不能给你的手写文件命名吗?
  • 我认为无论源代码是在文件中还是在其他东西中,这都是一个实现细节。如果可以通过标准输入向编译器提供源代码,则源代码可以在数据库中。
  • 我的例子可能有点偏离,但是如果你使用一些即时编译器,比如 TCC,即使你编译了,你也可以随时提供一些人类可读的源名称以便错误报告直接从记忆中。那就是有一个“文件名”并不意味着被存储为一个文件。
  • 肯定是<iostream>之类的实现文件可能不是文件(如果您明白我的意思),而不是开发人员编写的文件?

标签: c++ language-lawyer c++20 std-source-location


【解决方案1】:

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

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

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

几十年来一直如此。另见:

在 C++20 中引入std::source_location 并没有改变这种状况。只是有些代码不会有明确定义的源位置(或者可能定义明确,但意义不大)。实际上,我会说坚持使用文件定义 std::source_location 有点短视......虽然公平地说,它只是在 C++(和 C )。

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

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

运行生成的可执行文件打印&lt;stdin&gt;

源代码甚至可以来自互联网。

@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);
}

works on GodBolt(但不能在你的机器上工作——没有流行的编译器支持这个。)

您是语言律师吗?好的,那我们来参考一下标准..

语言标准中没有明确回答 C++ 程序源是否需要来自文件的问题。查看 C++17 标准 (n4713) 的草案,第 5.1 节 [lex.separate] 内容如下:

  1. 程序的文本保存在本文档中称为源文件的单元中。源文件连同所有头文件 (20.5.1.2) 和通过预处理指令 #include 包含的源文件 (19.2),减去由任何条件包含 (19.1) 预处理指令跳过的任何源代码行,称为翻译单元。

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

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

【讨论】:

  • 对于标准而言,该管道是“源文件”。
  • @melpomene:这些单元只是称为源文件,并不是说它们实际上必须是源文件。但我会编辑答案以包含此内容。
  • 刚刚用 GCC 试过这个:"echo '#include \nint main(){printf("%s\\n", __FILE__); return 1;}' | gcc -o test -xc -"(不带引号)。执行时,它会打印出 .
  • 我不明白它是如何成为“奖励功能”的。这是标准功能的合规结果。
  • 关于标准(和科学)中的术语、名称和概念的有趣之处在于:它们通常是原子的。也就是说,“源文件”不一定是“源文件”的“文件”,实际上,“文件”一词可能根本没有定义-与数学中的数字相比:没有“ number”,只有“自然数”、“有理数”、“实数”等
【解决方案2】:

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

__FILE__

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

source_location::file_name 的定义相同。

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

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


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

【讨论】:

  • @Yksisarvinen 我不知道规则的“推定”限定的确切意图,但我 假定 :) 这是文件名确实的澄清需要是绝对的或规范的,但从编译器的角度来看,相对名称就足够了。我可能是错的。
  • 我只能看到scanner-c++ 返回“左侧柜子,第三抽屉,第四个红色标签文件夹,第 17 页”
  • FWIW,在 POSIX 意义上,管道(或任何其他类似文件的东西)是“文件”——因此,stdin/stdout 是“文件”,而不是磁盘文件等。这种感觉。
  • @Yksisarvinen:委员会通常会考虑一些情况,即晦涩的实现可能有充分的理由做一些与普通行为相反的事情。在这样做的过程中,它依赖于编译器编写者来判断他们的客户是否会发现这种常见行为比某些替代方法更有用或更不有用。将这些事情留给实现者判断的事实可能被视为“模棱两可”,但这是故意的,因为优秀的编译器编写者会比委员会更了解客户的需求。
  • @dmckee ... 在一个废弃的厕所里,门上写着“小心豹子”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
  • 2021-10-31
相关资源
最近更新 更多