C和C++注释风格的区别

Difference in the style of giving comments between C and C++

C(/*..*/)和C++(//)的注释风格有区别吗?

MISRA C:2004 说

Rule 2.2 (required): Source code shall only use /* … */ style comments.

注意:当添加对 C99 的支持时,此规则已针对 MISRA C:2012 撤销

MISRA C++ 说

Rule 2.7.1 (required): The character sequence /* shall not be used with c style comments.

Rule 2.7.3 says suggested comment as // for c++

谁能解释为什么 MISRA 说在 C 中使用 /* 而在 C++ 中使用 //

规则 2.2 意味着 C 只允许 /**/ 注释,而规则 2.7.1 通过禁止在 C 注释中使用 /* 告诉不要嵌套 C 注释。他们没有关系。

C89 只有 /* ... */ 个评论。但是 C++ 风格的注释 // .. 在 C99 中被添加到 C 中。我认为 MISRA 只是试图保持一致,这样如果您在 C89/C90.

中编译 C 代码,C++ 风格的注释就不会成为问题

但这不再重要,因为现代 C 和 C++ 都支持两种风格的注释。

您可以阅读 MISRA 的推理原理:

MISRA-C-2004 rationale:

Rule 2.3 (required): The character sequence /* shall not be used within a comment.

C does not support the nesting of comments even though some compilers support this as a language extension. A comment begins with /* and continues until the first */ is encountered. Any /* occurring inside a comment is a violation of this rule.

Consider the following code fragment: /* some comment, end comment marker accidentally omitted <> Perform_Critical_Safety_Function(X); /* this comment is not compliant */

In reviewing the page containing the call to the function, the assumption is that it is executed code. Because of the accidental omission of the end comment marker, the call to the safety critical function will not be executed.

MISRA-C++ 2008 rationale:

Rule 2-7-1 The character sequence /* shall not be used within a C-style comment.

C++ does not support the nesting of C-style comments even though some compilers support this as a non-portable language extension. A comment beginning with /* continues until the first */ is encountered. Any /* occurring inside a comment is a violation of this rule.

您引用的 MISRA C 子句要求

形式的“行注释”
//    This is a line comment

不使用,支持形式为“C 风格”的注释

/*   Original C style comment
          Can extend across multiple lines
*/

这允许使用较旧的编译器,因为“行注释”仅在 1999 年引入,并且在此之前仅作为非标准扩展用于某些编译器。

你引用的MISRA C++子句(记忆中,MISRA C中也有类似的)要求“原始C风格注释”不得嵌套。所以,这是不鼓励的

/*   Warning:   non-standard nesting of comment
     /*   Nested comment
     */
*/

不鼓励这样做,因为对它的支持不是标准的,但可以配置一些编译器来支持它。因此,使用“嵌套注释”的代码可能会以不同的方式表现(包括使用一个编译器进行编译,而不是使用另一个编译器进行编译)并且以意想不到的方式进行。但是,没有嵌套注释的代码将按预期编译,无论编译器是否支持嵌套注释。

“行注释”的嵌套没有问题,因为 // 会导致编译器忽略行尾的所有内容。这在 C++ 中是可以的,因为(与 C 不同)所有 C++ 版本(甚至是准标准版)都支持“行注释”。 (如果使用二字母或三字母,则不一定如此,但 MISRA 也不鼓励使用它们)。

尽管 // 是 C90 编译器的一个非常常见的非标准扩展,但 C90 标准从未允许使用它。 MISRA 规则的基本原理是您应该遵循适用的语言标准。

所以很简单:

  • MISRA-C:2004 适用于仅允许 /* */ 评论的 C90。
  • MISRA-C++:2008 用于 C++,允许 // 注释(无论 C++ 版本如何)
  • MISRA-C:2012 适用于允许 // 注释的 C99。

由于上述原因,您引用的规则已在 MISRA-C:2012 中删除。考虑升级到 2012 MISRA 版本,因为它在很多方面都有改进。

简而言之,这些标准是帮助程序员在使用不同的编译器标准编译代码时,避免由于注释风格而导致编译器行为不一致。

这就是标准背后的基本原理。


更详细的答案:

这是因为在C99标准之前不支持//行注释。同时创建 MISRA-C 2004 文档以支持 C89/C90 标准。

Rule 2.2 (required): Source code shall only use /* … */ style comments.

This excludes the use of // C99 style comments and C++ style comments, since these are not permitted in C90. Many compilers support the // style of comments as an extension to C90. The use of // in preprocessor directives (e.g. #define) can vary. Also the mixing of /* … */ and // is not consistent. This is more than a style issue, since different (pre C99) compilers may behave differently

C99 之前的 C 行注释上检查 Lundin's answer on this post. Also, check this SO post

因此,这就解释了为什么 MISRA-C 2004 子句 post 需要使用 /*

出于同样的想法,MISRA-C++ 2008 标准不鼓励使用 /* - C 风格(多行)注释 - 在 C++ 中自 some compilers may generate errors 以来。它鼓励使用 // 因为它是 "original" C++ 注释样式。

来自 MISRA C 2004:

Rule 2.2 (required): Source code shall only use /* … */ style comments.

This excludes the use of // C99 style comments and C++ style comments, since these are not permitted in C90. Many compilers support the // style of comments as an extension to C90. The use of // in preprocessor directives (e.g. #define) can vary. Also the mixing of /* … */ and // is not consistent. This is more than a style issue, since different (pre C99) compilers may behave differently.

我认为这已经解释了一切,但我仍然会添加带有链接的解释。

在原始 C(C99 之前)中,没有 // 注释。 C++ 引入了双斜杠注释前缀 // 作为注释单行的方式。

为了更清楚,让我们逐行分析:

This excludes the use of // C99 style comments and C++ style comments, since these are not permitted in C90.

如今,gcc 等现代编译器也开始在 C90 模式下支持此类 //,但仍会发出如下警告:

warning: C++ style comments are not allowed in C90

但建议在C90 C中使用/*..*/注释

Many compilers support the // style of comments as an extension to C90.

这就是我上面所说的,但仍然不建议在 C90 C 中使用 //,因为代码不可移植。例如,该代码将使用 gcc 进行编译,但使用另一个没有扩展名的编译器将无法编译。

The use of // in preprocessor directives (e.g. #define) can vary.

我觉得这个意思已经很清楚了。它说 // 的用法在预处理器指令中不会保持一致。

Also the mixing of /* ... */ and // is not consistent.

怎么办?这是可能的。就像我上面提到的,它因编译器而异。在 C99 C 中,它基本上是一致的,但如果您谈论的是 C99 之前的编译器,那么它们是否支持 // 注释很重要。

This is more than a style issue, since different (pre C99) compilers may behave differently.

是的。因为这是MISRA 2004,主要是讲C90之前的C。这是因为大多数 C90 编译器不支持 //,因此你会得到一个错误。如果您使用的是 C99,则这是无效的。


预期问题

Why was there no // in pre C99 C, and then why was it introduced in C++? Is there a specific reason?

C 源自 BB 源自 BCPL// 是在 BCPL 期间创建的,因此 BCPl 使用了它们。它的继任者 B 开始使用 /*...*/,这是由 C 继承的。虽然,C++ 决定恢复 BCPL 评论,当然也使用了 /*...*/。当时的C-standard把//作为一个非标准特性

引入C99 C时,有注释//

What are // and /*...*/ comments called?

// 注释被称为单行注释,因为它们只能延伸到一行。

/*...*/ 注释称为多行注释,因为它们可以扩展到多行。

Is it compulsory to use only one kind of comment through your source code?

不,您可以使用任何一个,甚至可以同时使用两者。虽然,有人说只使用一种类型会使代码可读。见仁见智吧。

Is rule 2.2 of MISRA C 2004 outdated?

有点。最近发布的 MISRA 2012 具有这些更改。虽然,如果您认为 MISRA C 2004 是错误的,因为它只专注于 C99 之前的版本,但事实并非如此。我现在建议使用 MISRA 2012。

规则 2.7.1(强制):字符序列 /* 不得与 c 风格注释一起使用。

(强调)

我认为您只是误读了上述规则中 "with" 一词的含义,并从 "shall not be used for c style comments" 的意义上进行了解释。

如果使用 "within" 而不是 "with",规则可能会更清楚。