Это статически связано? - PullRequest
       3

Это статически связано?

1 голос
/ 10 сентября 2010

Скажите, что у меня есть программа на C, и в ней есть строка:

int a = 12;

Привязано ли значение 12 к 'a' во время компиляции?Или значение помещается в память во время выполнения, когда область действия программы достигает значения «a»?

А как насчет языков программирования, таких как Python и Ruby?

Существуют ли языки / экземпляры, где значениестатически связан с переменной?Я уже давно об этом думаю и, честно говоря, не могу придумать логической причины для статической привязки значения к примитивному типу.

Ответы [ 4 ]

9 голосов
/ 11 сентября 2010

Компиляторы и виртуальные машины эффективно «внедряют» языки программирования. Они должны делать только то, что определено языковой семантикой и доступно для данной программы, чтобы быть правильными.

Когда вы пишете определение определения int a = 12; в программе на C, вы сообщаете компилятору, что существует переменная с именем a, начальное значение которой установлено равным константе, равной двенадцати.

Если вы никогда не наблюдаете a, компилятор может полностью избавиться от него, потому что вы не можете определить разницу во время выполнения программы согласно спецификации языка. (Например, если вы должны были приостановить программу и сканировать стек в этой точке, значение 12 вообще не должно быть там. Его необходимость для нахождения в стеке компьютера составляет , а не часть спецификации языка .)

Если вы наблюдаете a, но обнаруживаете, что ваша программа не может изменить его значение, компилятор сделал вывод, что это на самом деле static const и может выполнить оптимизацию, называемую «постоянным распространением», чтобы подтолкнуть жестко закодированные двенадцать. в зависимые инструкции.

Если вы берете ссылку на a, а-ля int *aptr = &a;, то в спецификации языка сказано, что a должен иметь место в памяти (IIRC). Это означает, что, согласно спецификации, в памяти будет действительный слот целого размера (в стеке, в любой разумной реализации), который будет содержать 12.

На других языках есть, очевидно, другие спецификации. Технически, в динамических языках компилятор может выполнять аналогичные оптимизации. Если у вас есть функция Python:

def do_nothing():
    a = 12

Вы можете себе представить, что компилятор Python, который превращает текст языка в байт-коды, может полностью исключить тело этой функции (для педантов: кроме неявного return None). Традиционно реализации Python не имеют таких оптимизаций, потому что философия языка требует отладки, простоты реализации виртуальной машины и понимания программистом выше оптимизаций.

Есть также некоторые хитрые конструкции в динамических языках, которые усложняют вывод. Например, Python позволяет много проверять объект кода, который, как ожидается, будет работать в разных реализациях. Для получения / проверки трассировки стека и локальных аргументов активированных фреймов требуется не менее механизмов отката медленного пути, что значительно увеличивает сложность оптимизации. Мы отказываемся от поддержки некоторых из этих видов проверки уровня стека на уровне языка в JavaScript с помощью ECMAScript версии 5.

Сложно поддерживать отладчики, приступим к оптимизации!

2 голосов
/ 10 сентября 2010

Значение 12 статически не связано с a.Скорее, a привязан к ячейке памяти, которая инициализируется значением 12.

Если a был объявлен как const и его адрес ничего не брал, компилятору не понадобитсявыделить хранилище и может использовать его как константу времени компиляции, в этом случае значение 12 будет статически связано с a.

1 голос
/ 10 сентября 2010

Это действительно зависит от контекста использования переменных и включенных оптимизаций компилятора. Если переменная никогда не обновляется и не используется в достаточно маленькой области видимости, она, вероятно, будет скомпилирована в окончательном выводе, даже при самой легкой из оптимизаций. Если компилятор обнаружит, что переменная передана или обновлена ​​позже (или, возможно, обновлена ​​позже), он может загрузить целое число в стек. Это зависит от архитектуры, но если она обновляется только через некоторое время, а затем удаляется, она может загрузить ее в регистр, если сможет, и работать с ней там.

В CPython он может выполнять аналогичные оптимизации в некоторых случаях, если он может охватывать переменную (если она не глобальная, тогда она будет загружена в кучу). В обычном Ruby он тоже может делать что-то подобное. В Jython и JRuby они точно так же оптимизируют во время процесса JIT.

Я не полный эксперт, так как я написал только очень простые компиляторы, которые выводят в байт-код для JITed позже, и это было много лет назад.

0 голосов
/ 12 сентября 2010

Я думаю, a не может быть статически связан, потому что a не является константой, и это означает, что может быть более одного значения a одновременно (например, объявление a в рекурсивной функции) , Важно, чтобы каждое значение a должно иметь отдельный адрес в памяти, что означает, что a не может быть статически привязан к конкретному отдельному адресу памяти.

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