我来到了这个晦涩的东西......我想知道除了以下情况外,@ 符号是否有可能出现在有效 C/C++ 应用程序的源代码中:
- 一个
const char*
值,例如const char* addr = "xyz@gmail.com"
const char
值,例如char c = '@'
- 从未使用的宏:
#define NEVER_EVER ABC@
- 在注释掉的部分中
提问理由:好奇心:)
我会回答C语言。请注意,没有任何 C/C++ 这样的东西。两者都是独立的语言,C 不是C++的子集。
除了您描述的这些可能性之外,@
也可以放在标头名称中,但这不是常见的做法:
main.c:
#include <stdio.h>
#include "fancy@header.h"
int main(void)
{
foo();
return 0;
}
fancy@header.h:
static void foo(void)
{
printf("whatevern");
}
对于涵盖此内容的标准参考,您可以查看涵盖基本执行字符集(不包括@
字符(的 C11 §5.2.1/p3。本段还提供了可能允许@
字符的情况列表(强调我的(:
在基本执行字符集中,应有控制表示警报、退格键、回车符和新字符线。如果在源文件中遇到任何其他字符(除非在标识符、字符常量、字符串文本、标头中名称、注释或永远不会转换为令牌(,行为未定义。
如果是标识符,请参阅 C11 §6.4.2.1/p3:
标识符中的每个通用字符名称应指定一个ISO/IEC 10646 中的编码属于其中一个范围的字符在 D.1 中指定。71(首字母不应是通用的字符名称,指定其编码为一个字符D.2 中指定的范围。实现可能允许多字节不属于基本源字符的字符设置为出现在标识符中;哪些字符及其对应关系通用字符名称是实现定义的。
D.1(规范性(附录部分列出了允许的字符范围。正如您可能检查的那样,@
字符可以在 UCS 中表示为U+0040
,这超出了允许的范围:
00A8, 00AA, 00AD, 00AF, 00B2−00B5, 00B7−00BA, 00BC−00BE, 00C0−00D6,00D8−00F6, 00F8−00FF (...(
即使这样,编译器也可能允许@
字符作为语言扩展。C11 J.5.2/p1 专用标识符(通用扩展(包含:
下划线 _、字母和数字以外的字符,即不属于基本源字符集(如美元符号 $,或国家/地区字符集中的字符(可能出现在标识符中(6.4.2(.
例如,GCC允许$
以这种方式签名为GNU扩展:
在 GNU C 中,您通常可以在标识符名称中使用美元符号。这这是因为许多传统的 C 实现允许这样的标识符。但是,少数目标不支持标识符中的美元符号机器,通常是因为目标汇编程序不允许它们。
以上所有内容都没有任何问题。
@ 在名称(变量、函数、类等(中无效一些链接器实际上使用 @ 字符作为"at",意思是将符号与库相关联。(尝试在 Linux 中nm
一些可执行文件(;你会看到类似这样的内容:malloc@@GLIBC_2.2.5
表示malloc
取自 GLIBC_2.2.5。
在字符串和字符中,唯一有问题的字符是,它也用作转义字符,字符串和
'
中的"
必须转义才能不被翻译为字符串/字符的结尾。
在注释中,除了多行注释中的*/
将关闭注释外,没有任何限制。
从未使用过的宏在预编译后实际上并不存在,因此根本没有任何问题。