Что такое thunk?


131

Я видел его использование в программировании (особенно в области C ++) и понятия не имею, что это такое. Предположительно это шаблон дизайна, но я могу ошибаться. Кто-нибудь может привести хороший пример преобразователя?


10
Как и FYI, преобразователь также иногда называют «трамплином» (в общем случае, возможно, не в домене C ++).
Майкл Берр,

@MichaelBurr, единственный контекст, в котором я видел термин «батут», - это обходные пути, и в этом контексте батут - это не барабан.
user34660

1
Термин - это тип вещей, не имеющий конкретного определения, поэтому он может быть различным по определению.
user34660

Ответы:


132

A thunkобычно относится к небольшому фрагменту кода, который вызывается как функция, выполняет какую-то мелочь, а затем JUMPпереходит в другое место (обычно функцию) вместо того, чтобы вернуться к вызывающей стороне. Предполагая, что цель JUMP - обычная функция, когда она возвращается, она вернется к вызывающему преобразователю.

Преобразователи могут быть использованы для эффективной реализации множества полезных вещей

  • трансляция протокола - при вызове из кода, использующего одно соглашение о вызовах, в код, использующий другое соглашение о вызовах, thunkможно использовать a для надлежащего преобразования аргументов. Это работает, только если соглашения о возврате совместимы, но это часто так.

  • обработка виртуальных функций - при вызове виртуальной функции многократно унаследованного базового класса в C ++ необходимо исправить thisуказатель, чтобы он указывал в нужное место. А thunkможет это сделать.

  • динамическое закрытие - когда вы создаете динамическое закрытие, функция закрытия должна иметь возможность добраться до контекста, в котором она была создана. thunkМожет быть создан небольшой (обычно в стеке), который устанавливает контекстную информацию в некотором регистре (ах), а затем переходит к статическому фрагменту кода, который реализует функцию закрытия. Преобразователь здесь эффективно предоставляет функции один или несколько скрытых дополнительных аргументов, которые не предоставляются сайтом вызова.


13
Это лучшее объяснение, потому что оно объясняет, что такое преобразователь , а не то, что он обычно делает в типичных случаях использования для реализации различных вещей. Другие ответы слишком сосредоточены на этих конкретных реализациях, а не на общей идее.
SasQ

Не уверен насчет других компиляторов, но, в частности, Visual Studio, похоже, очень любит преобразователи. Насколько мне известно, он использует: преобразователи корректоров (для настройки this), замыкания конструкторов по умолчанию / копирования (для лучшей интеграции CRT-файлов, предоставляемых пользователем с параметрами по умолчанию, в основном для экспорта DLL или построения массивов), vcallпреобразователей (чтобы убедиться, что указатель на -member-functions работают правильно с виртуальными функциями), vtordispthunks (для классов, которые наследуют и переопределяют виртуальные функции из виртуальных баз, а также имеют предоставленные пользователем ctors и / или dtors), собственные оболочки (для вызова управляемого C ++ / CLI
Justin Time - Восстановить Монику

функции из собственного кода ISO C ++) и что-то под названием " UDT returning" (которое, похоже, является преобразователем для настройки определяемых пользователем типов, возвращаемых операторами, но я не уверен, как его сгенерировать; я думаю, что это устарело). Наверное, есть и другие. Я думаю, вы никогда не сможете сказать Microsoft, что thunkнет; Декарт гордился бы.
Джастин Тайм - Восстановить Монику

80

Слово thunk имеет как минимум три связанных значения в информатике. «Преобразователь» может быть:

  • кусок кода для выполнения отложенного вычисления (аналогично закрытию)
  • особенность некоторых реализаций таблиц виртуальных функций (аналогично функции-обертке)
  • отображение машинных данных из одной системной формы в другую, обычно по соображениям совместимости

Я обычно видел, что это используется в третьем контексте.

http://en.wikipedia.org/wiki/Thunk


3
Интересный; Я обычно слышу вторую форму, но думаю, это зависит от того, какую работу вы выполняете чаще,
Майкл Мрозек,

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

21

Термин thunk первоначально относился к механизму, используемому Royal Radar Establishment при реализации передачи по имени в их компиляторе Algol60 . В общем, это относится к любому способу вызвать динамическое поведение при обращении к явно статическому объекту. Этот термин был изобретен Брайаном Вичманном, который, когда его попросили объяснить передачу по имени, сказал: «Ну, вы идете загружать значение из памяти, а затем внезапно - бум - вы оцениваете выражение».

Преобразователи встроены в оборудование (см. KDF9, мэйнфреймы Burroughs). Есть несколько способов реализовать их в программном обеспечении, все очень зависят от машины, языка и компилятора.

Этот термин стал использоваться не только для передачи по имени, но и для включения любой ситуации, в которой явно или номинально статическая ссылка на данные вызывает динамическое поведение. Связанные термины включают «батут» и «будущее».


2
Спасибо за этимологию. Я ненавижу термины программирования, определение которых похоже на произвольный поиск в таблице.
Росс Роджерс

17

Некоторые компиляторы для объектно-ориентированных языков, таких как C ++, генерируют функции, называемые «преобразователями», в качестве оптимизации вызовов виртуальных функций при наличии множественного или виртуального наследования.

Взято из: http://en.wikipedia.org/wiki/Thunk#Thunks_in_object-oriated_programming


7

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

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


2
Для меня это
полная

2
Тогда синтаксический сахар для компиляторов? Почти, но не совсем так, как синтаксический сахар.
Дункан,

2
Может быть, синтаксический источник?
Джастин Тайм - Восстановить Монику

7

Этот вопрос уже задавался на SO, см.:

Что такое преобразователь, используемый в схеме или вообще?

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


5

Я был обеспокоен тем, что не нашел общего определения этого термина в «информатике», соответствующего его фактическому использованию, как это было известно мне исторически. Первое реальное столкновение, которое я могу вспомнить, где оно на самом деле было вызвано, было в дни OS / 2 и 16-32-битный переход. Похоже, «thunking» подобен иронии в его применении сегодня.

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

Таким образом, это ощущение похоже на синестезию отбрасывания из одной среды в другую, издающую (метафорически / как сравнение) звук «барабан».


1
Интересный совет. Меня тоже интересовала этимология этого слова, и я представил людей, играющих в «телеграф куста», где один из людей в потоке молча (и во многих случаях неосознанно) трансформирует сообщение по пути.
SasQ

5

Я собираюсь посмотреть это, но я подумал, что - это процесс, используемый 32-разрядным процессором для выполнения устаревшего 16-разрядного кода.

Я использовал это как аналогию того, как нужно ограничивать скорость разговора и какие слова использовать при разговоре с тупыми людьми.

Да, это ссылка на Википедию (часть про 32-битную версию, а не моя версию ботаника ).

https://en.wikipedia.org/wiki/Thunk

Большая часть литературы по преобразователям совместимости относится к различным платформам Wintel, включая MS-DOS, OS / 2, [8] Windows [9] [10] и .NET, а также к переходу от 16-битной к 32-битной адресации памяти. , По мере того, как клиенты переходили с одной платформы на другую, переходные блоки были необходимы для поддержки устаревшего программного обеспечения, написанного для старых платформ.

(курсив добавлен мной)


1

Самое раннее использование «преобразователя», о котором я знаю, относится к концу 50-х годов в отношении оценки аргументов передачи по имени в Algol60 при вызовах функций. Изначально Algol был языком спецификаций, а не языком программирования, и возник некоторый вопрос о том, как можно реализовать передачу по имени на компьютере.

Решение состояло в том, чтобы передать точку входа, по сути, лямбда. Когда вызываемый объект оценил параметр, управление провалилось - бум! - в контекст вызывающего, где была вычислена лямбда, и ее результат стал значением параметра в вызываемом.

В оборудовании с тегами, таком как машины Берроуза, оценка была неявной: аргумент мог быть передан как значение данных, как при обычном передаче по значению, или преобразователем для передачи по имени, с разными тегами в метаданных аргумента. , Аппаратное обеспечение операции загрузки проверяет тег и либо возвращает простое значение, либо автоматически вызывает лямбда-преобразователь.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.