Нет.
«Тип данных» переменной имеет значение только в исходном коде (и даже тогда только в некоторых языках). Он говорит компилятору, как обращаться с переменной.
Эти высокоуровневые типы данных не существуют как таковые в скомпилированном (нативном) коде. Они могут влиять на то, какие инструкции генерирует компилятор, но самим инструкциям все равно, представляют ли данные символ или число.
Переменные не существуют в аппаратном обеспечении. В оборудовании у вас есть области памяти и инструкции, которые работают с ними.
Переменная может рассматриваться как представление данных в ячейке памяти - если вы косите и смотрите на одну и ту же память немного по-разному (другая переменная с другим типом ссылается на одну и ту же ячейку), то одно и то же двоичное значение может иметь другое значение ,
Например, байт 0x41 можно интерпретировать как символ в кодировке UTF-8 A
. Это также можно интерпретировать как однобайтовое целое число 65
. Его также можно интерпретировать как один байт в многобайтовом целом числе или числе с плавающей запятой или один байт в многобайтовой кодировке символов. Это может быть битсет 0b1000001
. Все из одного байта в одной и той же ячейке памяти. В языке C вы можете увидеть этот эффект, приведя к этим различным типам.
Когда у вас «переполнение буфера», вы делаете что-то за пределами того, что может ожидать ваш компилятор или язык. Но, что касается оборудования 1 , вы записываете байты (одиночные или множественные) в область памяти. В ячейке памяти нет «типа». Фактически, оборудование даже не знает, что какой-то конкретный набор байтов создает массив или буфер в вашем коде.
Где бы вы в следующий раз не обращались к этой ячейке памяти в вашем коде, инструкции будут выполняться в соответствии с первоначальным определением. например, если они ожидали число там, они будут действовать на любые байты данных, как если бы они были числом.
Чтобы использовать ваш пример, предположим, что у вас int
4-байтовое (32-битное) целое число со знаком:
+-------------+--------------------------------------------+-----------+
| Source code | char[15] | int |
+-------------+--------------------------------------------------------+
| Memory |61|61|61|62|62|62|63|63|63|64|64|64|65|65|65|EF|BE|AD|DE|
+-------------+--------------------------------------------------------+
Вы можете видеть, что место в int
памяти теперь содержит 0xEFBEADDE
, предполагая систему с прямым порядком байтов 2 . Это подписанный 32-битный int -272716322
. Теперь, если вы интерпретируете ту же память, что и unsigned int ( uint
), она будет 4022250974
вместо этого. Для точно таких же данных в памяти значение полностью зависит от того, как вы их просматриваете.
1 Существуют некоторые механизмы, которые препятствуют записи в защищенные области памяти и могут привести к сбою программы, если вы попытаетесь это сделать.
2 x86 на самом деле является прямым порядком байтов, что означает, что вы интерпретируете байты, составляющие большее значение в обратном направлении. Так что на x86 вы бы вместо этого 0xDEADBEEF
, давали подписанные -559038737
или неподписанные 3735928559
.