在 // C++ 注释中使用 \\ 是否合法? (C++ 注释中的 LaTeX 方程)

Is it legal to use \\ in // C++ comment? (LaTeX equation in C++ comment)

出于文档目的,我需要在我的 C++ 注释中添加一些 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++ // 注释中合法使用 \ 吗?

根据cpp reference

C++-style comments tell the compiler to ignore all content between // and a new line.

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

g++ is warning about the escaped newline

Warn whenever a comment-start sequence ‘/’ appears in a ‘/’ comment, or whenever a backslash-newline appears in a ‘//’ comment. This warning is enabled by -Wall

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

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.

尽管 Whosebug 的语法突出显示,但第 2 行和第 5 行未编译。

如果您想知道,下一个标记是 ///*

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

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

which compiler is right?

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

which compiler is right?

两者都有。警告与 "legal usage of \" 无关,警告与多行注释有关。

在 C 中,行尾的 \ 字符表示忽略换行符。所以这两行:

// blabla\
abcabc

和:

// blabalabcbc

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

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

此类评论是合法的,但可能会产生意想不到的效果,因此发出警告。末尾带反斜杠的行之后的下一行是注释的延续,与开头的 // 无关。所以这个

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

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

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

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

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

If there is white space between a backslash and the end of a line, that is still a continued line. However, as this is usually the result of an editing mistake, and many compilers will not accept it as a continued line, GCC will warn you about it.

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

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

您应该对 literate programming techniques, and by tools like Doxygen 感兴趣。

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

请注意,使用文学编程技术需要花费大量时间。我个人但有限的经验是,它们更值得在 public 头文件上使用,而不是在实现细节和整个 translation units.

上使用

当然,您需要适当地了解更多有关build automation tools (such as GNU make or ninja) and configure them explicitly for running your nuwebdoxygen可执行文件的信息。