我对C语言中的行为感到困惑,其中注释末尾的反斜杠被忽略,如下所示。正如你在评论后看到的, “评论2:假人”最后有一个反斜杠。我期待的是编译错误,但没有得到任何。我正在使用Greenhills编译器。但是这种行为只与“\”字符有关。如果我使用其他东西,编译器会生成错误。
#include <stdio.h>
int x =0;
int y =2;
#define MACRO(x) (x+y)\
/*comment 1: Do addition of two operations*/ \
+\
(x*y)
/*comment 2: Dummy */\ <=============== Backslash at the end
#define MACRO1(y) (x+y)\
/*comment 3: Do Sub of two operations*/ \
-\
(x*y)
int main()
{
x = MACRO(x);
printf("value is : %d",x);
y = MACRO1(y);
printf("value is : %d",y);
return (0);
}
答案 0 :(得分:4)
在评论 中忽略反斜杠
两件事:
详细说明,引用C11
,章节§6.4.9
除了字符常量,字符串文字或注释之外,字符
/*
介绍评论。检查此类评论的内容仅用于识别 多字节字符,并找到终止它的字符*/
。
因此,在您的情况下,\
位于评论之外,并被视为源代码的一部分。
现在,考虑到 stray 反斜杠,如翻译阶段所述,章节§5.1.1.2/ p2
反斜杠字符(
\
)的每个实例后面紧跟一个换行符 删除字符,拼接物理源行以形成逻辑源行。只有任何物理源代码行的最后反斜杠才有资格成为其中一部分 这种拼接。 [....]
因此,在您的情况下,当到达实际编译阶段时,杂散反斜杠和后续换行符被删除,因此没有错误。
答案 1 :(得分:1)
在c中,要编写多行宏,每个语句都以\
结尾。在第二行中,评论在/* COMMENT */
内定义。所以外面的任何东西都是语法,\
是有效的。
这就是您的编译器可以使用\
。
额外\
是无关紧要的,编译器会忽略,因为没有声明可以进入。
您可以根据需要添加\
,编译器生成的代码也是一样。
#include <stdio.h>
int x =0;
int y =2;
#define MACRO(x) (x+y)\
/*comment 1: Do addition of two operations*/ \
+\
(x*y)
\
\
\
\
int main()
{
x = MACRO(x);
printf("value is : %d",x);
return (0);
}
生成的代码:
.file "Untitled1.c"
.globl _x
.bss
.align 4
_x:
.space 4
.globl _y
.data
.align 4
_y:
.long 2
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "value is : %d\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB10:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movl _x, %edx
movl _y, %eax
leal (%edx,%eax), %ecx
movl _x, %edx
movl _y, %eax
imull %edx, %eax
addl %ecx, %eax
movl %eax, _x
movl _x, %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE10:
.ident "GCC: (GNU) 5.3.0"
.def _printf; .scl 2; .type 32; .endef