用户定义的标识符是否以单个下划线开头没有问题?

Are user-defined identifiers beginning with a single underscore non-problematic?

这个标识符没有问题吗:

_var

C11,7.1.3 保留标识符,1

All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

由此可见,以单个下划线开头的用户定义标识符没有问题吗?

是的。只要:

  • 在块范围内(包括 enum/struct/union 标签)
  • 或者是 struct/union 成员
  • OR 是函数参数
  • _ 后面既没有大写也没有下划线

例如

struct X { int _a; };
int main() { int _a; }
void foo(int _a);

在main函数或者自定义函数里面,可以这么写

你不会得到任何编译错误。

int main()
{
 int _var;
 float _var1;
}

不对,有问题

你忘了再引用一句

All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

因此您不能声明以一个下划线后跟一个大写字母开头的标识符。

一般来说,使用下划线开头的标识符是一种糟糕的编程风格,因为代码的 reader 会认为这个标识符是由实现保留的。

Does it follow from this that user-defined identifiers beginning with a single underscore are non-problematic?

不,该列表项只是告诉您某些事情有问题。它没有声明其他东西是 non-problematic.

同一段告诉您,如果包含声明它们的 header,则 header 子句中列出的所有标识符都是保留的,可能用于任何用途,因此它们是有问题的。该段还列出了其他问题。

C 2018 6.4.2.1 5 和 6 告诉你,标识符长度超过 5.2.4.1 中列出的最小值(内部标识符 63 个字符,外部标识符 31 个字符)可能是个问题;如果两个标识符的区别仅超出实现强加的重要字符限制,则未定义该行为。

C 2018 6.4.2 还允许使用 implementation-defined 个字符的标识符,因此此类标识符可能适用于某些实现,但不适用于其他实现。