“const”是如何实现的?

时间:2011-10-25 17:21:28

标签: c++ c const

编译器,C或C ++(例如gcc)如何表彰const声明?

例如,在以下代码中,编译器如何跟踪变量ciconst并且无法修改?

int
get_foo() {
    return 42;
}

void
test()
{
    int i = get_foo();
    i += 5;

    const int ci = get_foo();
    // ci += 7;  // compile error: assignment of read-only variable ?ci?
}

5 个答案:

答案 0 :(得分:10)

与变量的任何其他位符号信息(地址,类型等)非常相似。通常有一个符号表存储有关已声明标识符的信息,每当遇到另一个对标识符的引用时,都会查询它。

(一个更有趣的问题是这些知识是仅在编译期间还是在运行期间出现。大多数语言在编译后丢弃符号表,因此即使标识符被声明,您也可以操纵编译的代码并强制使用新值const'。它需要一个复杂的运行时系统(和代码签名)来防止这种情况发生。)

答案 1 :(得分:3)

当然,这是每个编译器的实现,但简而言之,它将变量的constvolatile限定符(如果有)存储在其变量符号表中以及其他信息,如变量的类型以及它是否是指针/引用。

答案 2 :(得分:1)

编译器知道ciconst,因为你用行告诉了它

const int ci = get_foo();

当您将ci传递给其他函数或将其分配给其他变量时,编译器会通过阻止您执行可能会更改其值的任何操作来保留该常量。

例如,以下内容会产生编译器错误。

int *ci2 = &ci;
(*ci2)++;

因为编译器不允许你修改ci的值。

答案 3 :(得分:1)

我相信其他人可以详细说明,但简而言之,是的。编译器跟踪所有类型说明符,以便它知道ci的类型为“const int”,而不是“int”。

答案 4 :(得分:1)

正如其他人所说,编译器跟踪const的方式与编译器跟踪变量为int这一事实的方式相同。事实上,我已经读过,至少gcc认为const intint的一个不同的类型,因此它甚至不被跟踪为修饰符,它的跟踪方式与int完全相同。

请注意,您实际上可以通过指针转换来更改const的值,但结果是未定义的:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
        const int c = 0;
        printf("%d\n", c);
        ++*(int*)&c;
        printf("%d\n", c);
}

在我的机器上使用gcc打印

0
1

但是用g ++编译会给出

0
0