gpt4 book ai didi

通过标记连接创建包含通用字符名称的标识符

转载 作者:太空狗 更新时间:2023-10-29 16:28:54 24 4
gpt4 key购买 nike

我编写的这段代码通过标记连接创建包含通用字符名称的标识符。

//#include <stdio.h>
int printf(const char*, ...);

#define CAT(a, b) a ## b

int main(void) {
//int \u306d\u3053 = 10;
int CAT(\u306d, \u3053) = 10;

printf("%d\n", \u306d\u3053);
//printf("%d\n", CAT(\u306d, \u3053));

return 0;
}

此代码适用于 gcc 4.8.2 with -fextended-identifiers optiongcc 5.3.1 , 但不适用于 clang 3.3错误信息:

prog.c:10:17: error: use of undeclared identifier 'ねこ'
printf("%d\n", \u306d\u3053);
^
1 error generated.

和本地 clang(Apple LLVM 版本 7.0.2 (clang-700.1.81)),带有错误消息:

$ clang -std=c11 -Wall -Wextra -o uctest1 uctest1.c
warning: format specifies type 'int' but the argument has type
'<dependent type>' [-Wformat]
uctest1.c:10:17: error: use of undeclared identifier 'ねこ'
printf("%d\n", \u306d\u3053);
^
1 warning and 1 error generated.

当我使用 -E 选项让编译器输出带有宏扩展的代码时,gcc 5.3.1 发出了这个:

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"

int printf(const char*, ...);



int main(void) {

int \U0000306d\U00003053 = 10;

printf("%d\n", \U0000306d\U00003053);


return 0;
}

本地 clang 发出这个:

# 1 "uctest1.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 326 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "uctest1.c" 2

int printf(const char*, ...);



int main(void) {

int \u306d\u3053 = 10;

printf("%d\n", ねこ);


return 0;
}

如您所见,在 printf() 中声明和使用的标识符在 gcc 的输出中匹配,但在 clang 的输出中不匹配。

我知道通过标记连接创建通用字符名称会调用未定义的行为。

引自 N1570 5.1.1.2 翻译阶段:

If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), the behavior is undefined.

我认为这个字符序列 \u306d\u3053 可能“匹配通用字符名称的语法”,因为它包含通用字符名称作为其子字符串。我还认为“匹配”可能意味着通过串联产生的整个标记代表一个通用字符名称,因此此代码中不会调用此未定义的行为。

阅读 PRE30-C. Do not create a universal character name through concatenation ,我发现一条评论说这种连接是允许的:

What is forbidden, to create a new UCN via concatenation. Like doing

assign(\u0001,0401,a,b,4)

just concatenating stuff that happens to contain UCNs anywhere is okay.

还有一个日志显示 a code example like this case (but with 4 characters)替换为 another code example .

我的代码示例是否调用了一些未定义的行为(不限于通过 token 连接生成通用字符名称调用的行为)?或者这是 clang 中的错误?

最佳答案

您的代码不会触发您提到的未定义行为,因为通用字符名称 (6.4.3) 不是由 token 连接生成的。

并且,根据6.10.3.3,由于运算符##的左右两边都是一个标识符,产生的token也是一个有效的预处理token(也是一个标识符) ,## 运算符本身不会触发未定义的行为。

在阅读了关于标识符(6.4.2、D.1、D.2)、通用字符名称(6.4.3)的描述后,我很确定它更像是 clang 预处理器中的一个错误,它将标识符由 token 连接和普通标识符不同地产生。

关于通过标记连接创建包含通用字符名称的标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36787863/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com