为什么两个不同的枚举常数可以具有相同的整数值?
因为N1265 C99 标准草案在 6.7.2.2/3 "Enumeration specifiers" 明确允许它:
使用枚举器 with=
可能会产生枚举常量,其值与同一枚举中的其他值重复。
系统如何在内部区分 MON 和 TUE?
我认为这是不可能的,因为它们是编译时常量(6.6/6“常量表达式”)。因此,他们:
GCC 只是在编译时用汇编中的立即值替换枚举成员的使用。考虑:
#include <stdio.h>
enum E {
E0 = 0x1234,
E1 = 0x1234
};
int i = 0x5678;
int main() {
printf("%d\n", E0);
printf("%d\n", E1);
printf("%d\n", i);
return 0;
}
使用 GCC 4.8 x86_64 编译和反编译:
gcc -c -g -O0 -std=c89 main.c
objdump -Sr main.o
输出包含:
printf("%d\n", E0);
4: be 34 12 00 00 mov $0x1234,%esi
...
printf("%d\n", E1);
18: be 34 12 00 00 mov $0x1234,%esi
...
printf("%d\n", i);
2c: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 32 <main+0x32>
2e: R_X86_64_PC32 i-0x4
32: 89 c6 mov %eax,%esi
所以我们看到:
- 枚举成员用作立即
$0x1234
数,因此无法知道它们来自哪里
- 然而,变量
i
来自内存0x0(%rip)
(要重新定位),因此可以通过地址区分两个变量