2

我来到了这个晦涩难懂的事情......我想知道@符号是否有可能出现在有效的 C/C++ 应用程序的源代码中,除了以下情况:

  • 一个const char*值,例如const char* addr = "xyz@gmail.com"
  • 一个const char值,例如char c = '@'
  • 从未使用过的宏:#define NEVER_EVER ABC@
  • 在注释掉的部分

问的原因:好奇:)

4

2 回答 2

3

我会回答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("whatever\n");
}

对于涵盖此内容的标准参考,您可以查看涵盖基本执行字符集的 C11 §5.2.1/p3 ,其中不包括该@字符。本段还提供了可能允许@字符的案例列表(强调我的):

在基本执行字符集中,应该有代表警告、退格、回车和换行的控制字符。如果在源文件中遇到任何其他字符(标识符、字符常量、字符串文字、标头名称、注释或从未转换为标记的预处理标记除外),则行为未定义。

如果是标识符,请参阅 C11 §6.4.2.1/p3:

标识符中的每个通用字符名称应指定一个字符,其在 ISO/IEC 10646 中的编码属于 D.1 中规定的范围之一。71)初始字符不应是一个通用字符名称,该名称指定一个字符的编码属于 D.2 中规定的范围之一。一个实现可以允许不属于基本源字符集的多字节字符出现在标识符中;哪些字符及其与通用字符名称的对应关系是实现定义的。

D.1(规范性)附录部分列出了允许的字符范围。您可能会检查该@字符是否可以表示为U+0040UCS 这超出了允许的范围:

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 实现允许这样的标识符。但是,一些目标机器不支持标识符中的美元符号,通常是因为目标汇编器不允许它们。

于 2015-02-23T11:52:55.573 回答
1

以上都没有问题。

@ 在名称(变量、函数、类等)中无效。一些链接器实际上使用 @ 字符作为“at”,意思是将符号与库相关联。(尝试使用nmlinux 中的一些可执行文件)您会看到如下内容:malloc@@GLIBC_2.2.5表示malloc取自 GLIBC_2.2.5。

在字符串和字符中,唯一有问题的字符是\也用作转义字符的字符,而"在字符串和'字符中必须转义才能不被翻译为字符串/字符的结尾。

在评论中没有限制,除了*/将关闭评论的多行评论。

一个从未使用过的宏在预编译后并不真正存在,所以完全没有问题。

于 2015-02-23T11:43:15.577 回答