Ні.
"Тип даних" змінної є актуальним лише у вихідному коді (і навіть тоді лише в деяких мовах). Він розповідає компілятору, як поводитися зі змінною.
Ці типи даних високого рівня не існують як такі у складеному (рідному) коді. Вони можуть впливати на те, які інструкції створює компілятор, але самі інструкції не хвилюються, чи дані представляють символ чи цифру.
Змінні не існують в апаратному забезпеченні. У апаратному забезпеченні у вас є місця пам'яті та інструкції, що діють на них.
Змінна може розглядатися як перегляд даних у пам'яті - якщо ви косієте і дивитесь на одну і ту ж пам’ять дещо інакше (інша змінна з різним типом, що стосується одного і того ж місця), те саме двійкове значення може мати інше значення .
Наприклад, байт 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
. Тепер, якщо ви інтерпретуєте ту саму пам'ять, що і без підписаного int ( uint
), це було б 4022250974
замість цього. Для абсолютно тих самих даних у пам'яті сенс повністю залежить від того, як ви їх переглядаєте.
1 Існують деякі механізми, які перешкоджають запису в захищені області пам’яті, і вони збивають вашу програму, якщо ви спробуєте це зробити.
2 x86 насправді малоеквізичний, це означає, що ви інтерпретуєте байти, складаючи більшу величину назад. Тож на x86 ви б натомість мали 0xDEADBEEF
, даючи підписані -559038737
чи непідписані 3735928559
.