Как реализовано «const»? - PullRequest
       7

Как реализовано «const»?

7 голосов
/ 25 октября 2011

Как компилятор C или C ++ (например, gcc) учитывает объявление const?

Например, в следующем коде как компилятор отслеживает что переменная ci равна const и не может быть изменена?

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 ]

10 голосов
/ 25 октября 2011

Как и любой другой бит символьной информации для переменных (адрес, тип и т. Д.).Обычно существует таблица символов, в которой хранится информация об объявленных идентификаторах, и к ней обращаются всякий раз, когда встречается другая ссылка на идентификатор.

(Более интересный вопрос заключается в том, присутствуют ли эти знания только во время компиляции или даже во время выполнения. Большинство языков отбрасывают таблицу символов после компиляции, поэтому вы можете манипулировать скомпилированным кодом и принудительно устанавливать новое значение, даже если идентификатор был объявлен как «const». Для предотвращения этого требуется сложная система времени выполнения (и подпись кода).)

3 голосов
/ 25 октября 2011

Конечно, это реализация каждого компилятора, но в двух словах, он хранит квалификаторы const и volatile переменной (если есть) в своей таблице символов переменных вместе с другой информацией, такой как тип переменной и является ли это указатель / ссылка.

1 голос
/ 25 октября 2011

Как уже говорили другие, компилятор отслеживает const так же, как компилятор отслеживает тот факт, что переменная является int.На самом деле, я читал, что, по крайней мере, gcc считает const int отличным от int типом, поэтому он даже не отслеживается как модификатор, он отслеживается точно так же, как 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
1 голос
/ 25 октября 2011

Я уверен, что другие могут уточнить, но в общем, да. Компилятор отслеживает все спецификаторы типа, чтобы он знал, что ci имеет тип "const int", а не "int".

1 голос
/ 25 октября 2011

Компилятор знает, что ci равно const, потому что вы сказали это так со строкой

const int ci = get_foo();

Когда вы передаете ci другим функциям или присваиваете его другим переменным, компилятор сохраняет это постоянство, не давая вам делать что-либо, что может потенциально изменить его значение.

Например, следующее вызывает ошибку компилятора.

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

Поскольку компилятор не позволит вам изменить значение ci.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...