如何禁用 C 头文件中的语法检查

我正在将 Lua 代码嵌入 C++ 中,写起来像这样是可以的

char const *lua_scripts = R"rawstring(

-- Lua 代码

)rawstring";

但是字符串中的 Lua 代码没有语法高亮,所以我将它分成了三个文件: 第一个文件叫做 head.txt

char const *lua_scripts = R"rawstring(

第二个文件叫做 body.lua

 -- Lua 代码

第三个文件叫做 tail.txt

)rawstring";

然后原来的 cpp 文件改成了

#include "head.txt"
#include "body.lua"
#include "tail.txt"

但是当我进行编译时,会报告语法错误,因为编译器会在包含之前检查文件。那么我该如何禁用编译器检查语法呢?

原文链接 https://stackoverflow.com/questions/70240110

点赞
用户1566221
用户1566221

在 C++ 中,程序在预处理之后被解析。但是将输入分成词素是在预处理之前完成的。预处理器的输入是一系列标记流,而不是字符流。

因此,一个标记不能跨越两个输入文件。而字符串字面量是一个单独的标记。

你也不能将预处理器指令分成两个文件,因此 #endif#else 等必须和 #if#ifdef 在同一个文件中,文件中的最后一行也不能以反斜杠换行符结束。

你可以轻松地编写自己的小合并程序,将 C++ 和 Lua 源文件构建为一个 C++ 文件。你甚至可以用 Lua 编写它,它并不是那么复杂。或者你可以使用 M4 宏处理器,在你的编译环境中可能已经安装了它。

2021-12-06 03:15:36
用户9837301
用户9837301

当 C++ 代码被编译时,会发生 九个翻译阶段,其中第三阶段是识别字符串字面量的阶段,第四阶段是预处理器。当编译器到达 #include 指令时,原始源文件中所有字符串字面量已经被识别并标记。在预处理器完成后,不会再有其他对源文件的扫描以寻找更多字面量。

当预处理器引入文件时,该文件在被插入原始源文件之前会经历前四个翻译阶段。这与常见的、简单的头文件直接复制到源文件的感知略有不同。头文件不是逐个字符地复制,而是逐个标记地复制,其中“标记”的意思是“预处理标记”,包括诸如标识符、运算符和字面量等东西。

在实际操作中,这种简化视图足够满足您的需要,直到您尝试使语言元素跨文件边界。特别地,注释和字符串字面量都不能从一个文件开始并延伸到另一个文件。(还有其他的例子,但它们有点牵强附会。)您尝试让一个字符串字面量从一个文件开始,延伸到第二个,然后在第三个文件结束。这是不行的。

当预处理器引入 head.txt 时,前三个阶段将其解析为五个预处理标记,然后是一个未终止的字面量。这是被复制到源文件中的内容。请注意,未终止的字面量仍然是一个未终止的字面量;它不会变成一个寻找结尾的字面量。

当引入 body.lua 时,它会像任何其他头文件一样处理。预处理器不关心扩展名。文件被引入,并像任何其他 #include 一样受到翻译阶段的影响。第三阶段将使用 C++ 语法规则,识别在 body.lua 中开始的字符串字面量,但是 body.lua 的任何部分都不会成为从 body.lua 外开始的字符串字面量的一部分。第三阶段,包括字符串字面量的识别,仅在该文件中独立地进行。

您的方法已经失败了。


那么我怎么禁用编译器检查语法呢?

你不能禁用编译器语法检查。这就像问你如何让一个人在不挑选字母和单词的情况下读书一样。你要求编译器处理你的代码,这其中的第一步就是确保代码是可理解的,即具有有效的语法。正是像这样的问题提醒我们 XY 问题 仍然很普遍。

不过,幸运的是,你提到了你的真正问题:“没有语法高亮”。不幸的是,你没有提供足够关于你真正问题的信息,比如提供语法高亮的程序是什么。我将以下内容提交给两个不同的语法高亮器;一个将 Lua 代码视为 Lua 代码,而另一个则没有。

R"rawstring(
 -- lua code
)rawstring"

如果你愿意忽略第一行和最后一行的高亮,而你的编辑器成功地应用了所需的语法高亮,你可以将其用作你的 body.lua 文件。然后,以下 C++ 代码应该可以工作。

char const *lua_scripts =
#include "body.lua"
;

语句的识别要直到第七个阶段——在预处理器之后——所以你 可以 将语句分割开放在多个文件中。

2021-12-10 02:00:59
用户4183058
用户4183058

你可以在构建前使用 Unix 下的 xxd 工具预处理 body.lua 文件,步骤如下:

xxd -i body.lua body.xxd

然后在你的 C++ 代码中使用:

#include "body.xxd"
const std::string lua_scripts(reinterpret_cast<char *>(body), body_len);
2022-07-06 22:25:05