【问题标题】:Is it legal to use \\ in // C++ comment? (LaTeX equation in C++ comment)在 // C++ 注释中使用 \\ 是否合法? (C++ 注释中的 LaTeX 方程)
【发布时间】:2020-06-01 05:57:36
【问题描述】:

出于文档目的,我需要在我的 C++ cmets 中添加一些 LaTeX 方程,例如:

//
// \begin{eqnarray*}
//   y_1 &=& x_1 \\
//   y_2 &=& x_2 
// \end{eqnarray*}
//
int main() {}

使用 clang++(版本 9.0.1-10)我可以毫无问题地编译我的代码:

clang++ -Wall prog.cpp 

但使用 g++(版本 9.2.1)

g++ -Wall prog.cpp 

我收到此警告:

prog.cpp:3:1: warning: multi-line comment [-Wcomment]
    3 | //   y_1 &=& x_1 \\
      | ^

我的问题:哪个编译器是正确的?我可以在 C++ // 评论中合法使用 \\ 吗?

【问题讨论】:

  • 我安装的 clang++ 也发出了这个警告。

标签: c++ g++ language-lawyer clang++


【解决方案1】:

合法吗?是的。容易出错吗? 是的。这就是您收到警告的原因。

C/C++ 标准首先有一个标记(首先处理):\

此标记删除换行符。考虑以下代码:

1.  // the below code is commented out \
2.  despite not having a comment at the beginning of the line
3.  
4.  // it's important to be careful because \\
5.  int not_compiled_code = 0;
6.  // the above code is not compiled.

尽管 stackoverflow 的语法高亮显示,但第 2 行和第 5 行未编译。

如果您想知道,接下来的标记是 ///*

// /* incomplete block comment
int compiled_code = 0;

/*
// this entire line isn't commented */ int compiled_code_2 = 0;

哪个编译器是正确的?

两者都有,因为警告与标准无关。它们编译成功,这才是最重要的——它们都完全符合标准。

【讨论】:

    【解决方案2】:

    这样的 cmets 是合法的,但它们可能会产生意想不到的影响,因此发出警告。末尾带有反斜杠的行之后的下一行是注释的延续,与开头的 // 无关。所以这个

    // \\
    Hey dude!
    int main () {}
    

    是一个有效的 C++ 程序。不,最后一个反斜杠之前的反斜杠不能作为转义符。

    如果您想避免警告,请在行尾添加 LaTeX 注释:

    // y_1 &=& x_1 \\ % look ma, no warning
    

    请注意,反斜杠和换行符之间的简单空格不一定能解决问题。 GCC 文档说:

    如果反斜杠和行尾之间有空格,则仍是续行。但是,由于这通常是编辑错误的结果,并且许多编译器不会接受它作为续行,因此 GCC 会警告您。

    【讨论】:

    • 如果我没记错的话,续行是反斜杠换行符。所以,如果我是对的,反斜杠后的简单空格应该可以修复它,但是空格是不可见的,并且 LaTeX 注释更好。 ;-)
    • @Scheff :“反斜杠后的简单空格应该修复”我也这么认为。它没有。 Clang 甚至对此发出警告。
    • 关于反斜杠后的简单空格:这似乎在 MSVC 中有效,但在 g++ 和 clang 中无效。因此,LaTeX 注释(或任何其他非空格)实际上是解决方案。 g++ and clang on CompilerExplorerMSVC on regex
    • @n.'pronouns'm。是的。我只是摆弄了一下。 MSVC 似乎是唯一支持它的。
    【解决方案3】:

    根据cpp reference

    C++ 风格的 cmets 告诉编译器忽略 // 和新行之间的所有内容。

    所以你的评论应该是合法的。请注意,g++ 只是给出警告,而不是错误。

    g++ is warning about the escaped newline

    每当注释开始序列“/”出现在“/”注释中,或每当反斜杠换行符出现在“//”注释中时都会发出警告。此警告由 -Wall 启用

    【讨论】:

    • 是的,但 `\` 传统上用于换行(stackoverflow.com/a/969402/2001017)...问题是我不知道标准到底是怎么说的...
    • 不违法,g++只是觉得它的风格很差
    【解决方案4】:

    哪个编译器是正确的?

    两者兼而有之。警告不是关于“\ 的合法使用”,而是关于多行注释。

    在 C 中,行尾的 \ 字符意味着忽略换行符。所以这两行:

    // blabla\
    abcabc
    

    和:

    // blabalabcbc
    

    完全等价。双反斜杠\\ 只是一个反斜杠\\ 转义,所以它首先被反斜杠替换,然后预处理器检测反斜杠后跟换行符并删除换行符。这就是为什么它很危险。

    int a = 1;
    // increase a \\
    a++;
    printf("%d\n", a); // will print `1`
    

    【讨论】:

    • \\ 不是转义的 \ 因为它不是字符串。
    【解决方案5】:

    一个实用的解决方案是使用/* 多行cmets。所以代码

    /***
     \begin{eqnarray*}
       y_1 &=& x_1 \\
       y_2 &=& x_2 
     \end{eqnarray*}
    ***/
    

    您应该对literate programming 技术以及Doxygen 等工具感兴趣。

    我的建议是尝试Nuweb(至少如果您在 Linux 上编码),特别是对于您的公共(和 LaTeX 文档)头文件。您将编写一个 Nuweb 源文件(一些 *.nw 文件),一方面会生成 LaTeX,另一方面会生成 C 代码(例如一些头文件)。

    请注意,使用识字编程技术需要大量时间。我个人但有限的经验是,与实现细节和整个translation units相比,它们更值得在公共头文件上使用。

    当然,您需要了解有关build automation 工具(例如GNU makeninja)的更多信息,并明确配置它们以适当地运行您的nuwebdoxygen 可执行文件。

    【讨论】:

    • 我必须坚持 C++ 风格的 '//' 注释,以便某些工具使用 Org-Mode 后端生成文档
    • 顺便说一句,我们是同事。请随时用法语与我联系basile.starynkevitch@cea.fr,然后详细说明您的实际问题和项目
    • 我认出了你:)。是的,我会给你发一封电子邮件。这是我自己的提取评论以生成一些 OrgMode 文档的工具。 C cmets 的问题在于,它们的解析比“单行”注释(如 //、# 或 % 等)稍微复杂一些......我们通常在其他语言中看到
    猜你喜欢
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 2012-07-28
    • 2014-06-23
    • 2010-10-07
    • 1970-01-01
    相关资源
    最近更新 更多