2016-01-04 5 views
2

Этот вопрос, возможно, был дан ответ раньше, но я искал эти форумы и Google, но не думаю, что я попросил правильную вещь самым кратким образом, поэтому приношу свои извинения, но я попытаюсь объяснить свой вопрос дальше:Как программа знает, какой тип переменной?

Скажем, например, у вас есть переменная, назовем ее x и она относится к куску памяти, который содержит двоичное значение 01000001. Мне было интересно: где хранится информация типа для этого двоичного представления?

Есть как система отображения памяти, такая как словарь, который отображает двоичное представление в некоторый предопределенный список типов, например. 0000 для представления int и 0001 для представления char, например?

Я чувствую, что это не так, поскольку это приведет к увеличению объема накладных расходов, которые будут расти, например, например, введены более определенные пользователем типы или создано больше переменных. Но я полагаю, что это может иметь место для weakly языков. (Или, может быть, нет) Но как насчет strongly?

+0

Я не уверен, но это должен быть компилятор. Когда он переводит ваш код на машинный язык, он смотрит на переменные типы. Но как насчет программ и функций, которые могут иметь аргументы любого типа? Они просто используют _format_ (например, 'printf') или позволяют создать свою собственную функцию, которую они используют (' qsort'). Как я знаю, ASM не имеет никаких типов (я не уверен) – stek29

ответ

5

Мне было интересно: где хранится информация типа для этого двоичного представления?

Его не нужно хранить. Статически типизированная программа компилируется в последовательность инструкций, нацеленных на некоторые ячейки памяти. Static typechecking проверяет, что инструкции работают в ячейках памяти, содержащих соответствующие данные. Однако во время выполнения инструкции могут быть выполнены без какой-либо проверки.

Рассмотрим эту простую функцию C:

void increment(int* x) { 
    (*x) += 1; 
} 

Во время компиляции, компилятор будет проверять, что значение за указателем содержит значение типа int. Сам указатель - это всего лишь число, и, следовательно, операция приращения может и будет сделана независимо.

Следовательно, эта программа хорошо типизирована, но вы теряете вышеупомянутую гарантию.

void increment(void* x) { 
    (*(int*)(x)) += 1; 
} 

Главное внимание здесь заключается в том, что инструкции низкого уровня работают с любыми видами данных таким же образом.

0

Статические типы неизвестны во время выполнения: они необходимы только во время компиляции, например, для разрешения перегрузки и проверки того, что типы соответствуют операциям, которые вы хотите запустить, поэтому компилятор избавляется от них при оптимизации.

Некоторые языки поддерживают динамически определенные типы, такие как C++ (только для классов с виртуальными методами)/java/C#, но также и python и javascript. Информация о том, какой тип этот объект находится во время выполнения (т. Е. «Реальный» тип объекта, а не тип переменной, удерживающей его для полиморфизма) используется для разрешения вызова метода во время выполнения. Эта информация хранится обычно как указатель на структуру, определяющую тип. Накладные расходы времени выполнения, имеющие много типов, имеют постоянное количество памяти для каждого класса. Обычно это не важно, но есть некоторые исключения (например, в Javascript при написании замыканий вы создаете новый тип для каждого объекта, который вы создаете, в некоторых браузерах это довольно дорого). У вас могут быть тяжелые накладные расходы во время компиляции: это часто случается в шаблонах на C++.