在C或C ++应用程序中使用@

时间:2015-02-23 11:32:21

标签: c++ c validation correctness security-by-obscurity

我遇到了这个不起眼的事情......我想知道 @ 标志是否有可能出现在有效的C / C ++应用程序的源代码中,除了以下内容之外情况:

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

提问的理由:好奇心:)

2 个答案:

答案 0 :(得分: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(规范性附录)部分列出了允许的字符范围。正如您可能会检查@字符在UCS中可以表示为U+0040,这超出了允许的范围:

  <00> 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 extension方式签名:

  

在GNU C中,您通常可以在标识符名称中使用美元符号。这个   是因为许多传统的C实现允许这样的标识符。   但是,少数目标不支持标识符中的美元符号   机器,通常是因为目标汇编程序不允许它们。

答案 1 :(得分:1)

以上所有内容都没有问题。

@在名称(变量,函数,类等)中无效 一些链接器实际上使用@字符作为&#34; at&#34;将符号与库相关联的含义。 (尝试nm linux中的一些可执行文件) 您会看到类似这样的内容:malloc@@GLIBC_2.2.5表示从{GLIBC_2.2.5}获取的malloc

在字符串和字符中,唯一有问题的字符是\,它也用作转义字符,字符串中的"和字符中的'必须转义为不转换作为字符串/字符的结尾。

在评论中除了多行注释中的*/之外没有任何限制,这将关闭评论。

在预编译之后,一个从未使用过的宏实际上并不存在,所以根本没有问题。