【发布时间】:2020-07-03 08:46:30
【问题描述】:
有这个:
#include <stdio.h>
#include <stdlib.h>
void f(const char *str){
char *p = (char*)str;
*p=97;
}
int main(){
char c;
f(&c);
char *p = malloc(10);
if (p) { f(p); printf("p:%s\n",p); free(p); }
const char d = 0; //only this part in interest
f(&d); // here the function modifies the the char, but since it is NOT in rodata, no problem
printf("d:%c\n",d);
printf("c:%c\n",c);
}
会产生气体:
...
.L3:
# a.c:16: const char d = 0;
movb $0, -10(%rbp) #, d
# a.c:17: f(&d);
leaq -10(%rbp), %rax #, tmp98
movq %rax, %rdi # tmp98,
call f #
# a.c:18: printf("d:%c\n",d);
movzbl -10(%rbp), %eax # d, d.0_1
movsbl %al, %eax # d.0_1, _2
movl %eax, %esi # _2,
leaq .LC1(%rip), %rdi #,
movl $0, %eax #,
call printf@PLT #
# a.c:20: printf("c:%c\n",c);
...
这里,d const char 变量只有moved 入栈,但它的名字(撕裂位置)不在.section .rodata,这是为什么呢?当它具有 const 修饰符时。如果它是char* 字符串,那么它 会自动放置在rodata 上(char* 甚至不需要 const 修饰符)。我在某处读过 constness 是继承的(这意味着一旦使用 const 修饰符声明了一个变量,那么即使强制转换导致cast-away-constness,也不会改变 constness - 即它将保留)。但是这里甚至没有考虑 const char 修饰符(直接通过堆栈操作,就像数组一样)。为什么?
【问题讨论】:
-
它是一个非静态的const local变量,所以它存储在堆栈中。
标签: c x86 char compiler-construction