| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > статическое и динамическое связывание |
| Автор: Gunslinger 11.8.2008, 10:56 |
| читаю "Основные концепции языков программирования", 4ю главу, где Страуструп про переменные пишет. Я так понял, статическое связывание было придумано только для ускорения компилирования и быстрой работы программ, где есть такие переменные. Но имеет ли смысл понимание и использование соответствующих типов связывания сейчас, когда настольные ПК (а тем более серваки) обладают гораздо большими скоростными возможностями? Для мобильных устройст, систем реального времени и прочих малоресурсных систем - смысл есть. Для ПК - преимущества static кажется призрачным, имхо. |
| Автор: cutwater 11.8.2008, 11:24 |
| Имеется ввиду раннее и позднее либо как называют статическое и динамическое. Вы ответьте на вопрос, при современных технологиях на велосипед можно навесить реактивный двигатель, так стоит ли отказываться от велосипеда. Раннее связывание происходит на этапе компиляции и переносить его в рантайм смысла не имеет. Зачем? Позднее связывание имеет место только для виртуальных методов, когда в процессе исполнения заполняется vtable. |
| Автор: Gunslinger 11.8.2008, 11:48 | ||||
Эти преимущества static я знаю. Меня интересует другое его преимущество - скорость работы программы, когда в место динамических переменных используются статические (естественно, где нет списков и прочих меняющихся структур). Добавлено через 3 минуты и 9 секунд
что это? Ничего об этом не знаю. Думал обычный двоичный код, который процессор берет, обрабатывает и кладет обратно. Только один код программы. Что проводит такие проверки? |
| Автор: mes 11.8.2008, 12:14 | ||||||
для обычных программ это преимущество несущественное.
вот этот код и берет переменную, определяет ее тип и в зависимости от типа выбирает нужную реализацию функции для текущей задачи. Например Вам нужно инкрементировать n-j элемент массива . mas [n] = mas[n]+1; а где то выше идет такое : n=1.34523; mas = 2; при строгой статической проверке типов компилятор завопит.. А как должна поступить программа при динамическом связывании типов если у нее нет проверки ?
в той главе описываются не статические и динамические переменные, а статическое и динамическое связывание типов.. |
| Автор: cutwater 11.8.2008, 12:36 |
| Автору читать полиморфизм и механизм полиморфизма. |
| Автор: Gunslinger 11.8.2008, 16:31 | ||||
Лабораторные? А игры и моделирование-визуализация?
я надеюсь смысл вопроса от этого не потерян? Как я понял, связывание типов - это выделение компилятором памяти либо до выполнения программы (при компиляции), либо во время выполнения.
т.е. компилятор к коду самой программы (инструкции, функции и прочее написанное программистом) добавляет что-то вроде служебной информации - в данном случае проверки типов? Добавлено через 3 минуты и 34 секунды теоретически имею предтавление. на практике реализовывал в виде перегрузки функций. а здесь это что значит? |
| Автор: cutwater 11.8.2008, 16:54 | ||||||||||||
| Ты понял не правильно. Это не выделение памяти в стеке или в куче. На этапе компиляции вся информация о типе без виртуальных ф-ций известна. Если в классе есть хотя бы один виртуальный метод, то создается vptr и vtable, vtable (виртуальная таблица адресов) хранит в себе адреса виртуальных функций и создается во время создания объекта в рантайм. Это сказывается на быстродействии и на безопасности типов. Пример
Случай 1
тут и так все понятно вывод
Случай 2
а вот тут неожиданность. результат
компилятору не известно о том что foo перегружен в дочернем классе, поэтому будет вызван метод базового класса. но если в базовом классе объявить метод foo виртуальным, то во время создания объекта дочернего класса в виртуальной таблице адрессов методу foo будет соответствовать адрес перегруженного метода.
Собственно я попытался в 2х словах объяснить механизм работы. ЕМНИП Как раз последний пример и относится к позднему связыванию |
| Автор: mes 11.8.2008, 17:35 | ||
вопрос как я понимаю был этот :
1 Понимание программисту всегда необходимо.. Он должен точно представлять что делает. При том что разница далеко не в скорости выполнения 2 Использование обуславливается в первую очередь выбором языка. Да сегодняшние компьютеры настолько мощны, что для решения большинства бытовых задач можно безбоязненено в плане скорости использовать язык с динамическим связыванием типов. в узких местах такие как вывод на экран, например для 3д графики или шейдеров используются специальные библиотеки , которые экономят скорость на всем включая также и статическое связывание типов. |
| Автор: Gunslinger 11.8.2008, 18:20 | ||||
да, так. и все таки
К вопросу о том, какую инфу добавляет компилятор к исходнику - спасибо, интересно было узнать. Но я так и не понял про связывание типов. Те примеры, которые ты привел - это демонстрация полиморфизма. Уточню еще раз: статическое связывание типов - переменная объявлена (выделен размер = типу) и инициализирована (присвоено значение). до конца работы программы ее значение не изменится. проводится при компиляции. динамическое связывание типов - переменная объявлена (выделен размер = типу), но не инициализирована. инициализация (запись значения) происходит во время работы программы. ps больше ничего не приводит. |
| Автор: Alek86 11.8.2008, 18:35 | ||
это называется "константа"
заметь, после тире у тебя - ни слова о типе |
| Автор: mes 11.8.2008, 19:15 | ||||
статическое связывание типа - это такой метод работы с ячейкой пямяти , когда тип хранимого там значения известен на момент компиляции и не может быть изменен в процессе выполнения проги. динамическое связывание - это такой метод работы с ячейкой пямяти , когда тип хранимого там значения неизвестен (или не проверяется) на этапе компиляции, а становится известен (и зачастую может быть изменен) только в процесе выполнения. Для обеспечения такой возможности выделяется дополнительная память под хранения типа. Виртуальные функции в с++ имеют ограниченное динамическое связывание.
именно так.. При каждом вызове функции выбирается та которая больше подходит для текушего типа. В случае ненахождения и конфликта возникает ошибка. При статическом возникает в момент компиляции, при динамическом в момент выполнения.. Способы проверки и реакции на ошибку зависят от конретного языка и компилятора. Хочу также отметить что виртуальные функции в данном контексте обладают статическим связыванием, и не позволяют сделать перегрузку по их динамическому типу. Для обхода этого ограничения используют двойную диспетчеризацию, которая предоставляет перегрузку по динамическому типу, сохраняя проверку типов на этапе компиляции.. не понял относительно своего первого вопроса ? |
| Автор: W4FhLF 11.8.2008, 19:38 |
| Отчасти ведь auto и decltype в С++0х будут связаны с вопросом связывания. И хотя в техническом плане связывание так же будет происходить в compile-time, для программиста это будет смотрется немного иначе, ведь явно указывать тип не понадобится, хотя необходимо знать, что где-то он уже указан. |
| Автор: Gunslinger 12.8.2008, 08:55 | ||||||
попутал да. вопрос решен - это был чисто обывательский интерес. Просто сейчас пошел уже не обывательский. К теме топика уже мало отношения имеет, если модератор закроет тему - создам отдельную.
Недопонимаю. Уточняющие вопросы:
1. тип же всегда известен, в с++ только так переменные и объявляются. Или может быть иначе? 2. Как тип переменной может быть изменен в процессе выполнения? Имеется ввиду преведение типов? 3. Под статическим связыванием типов я понимаю следующее: int y=2; - тип известен, компилятор выделяет под него память размером int (до выполнения, при компиляции). значение тоже известно - компилятор записывает его в ячейку int y. 4. Создает ли компилятор доп инфу, как в случае с виртуальными функциями для объявленных переменных, но не инициализированных? int x; или int *p=new int[]; Добавлено через 10 минут и 47 секунд
имею ввиду соответствие название_переменной=адрес |
| Автор: Partizan 12.8.2008, 09:10 | ||||||
компилятор только компилирует....никакой памяти он "до выполнения, при компиляции" не выделяет...
Вам думаете, что int x; - это позднее связывание? |
| Автор: Gunslinger 12.8.2008, 09:40 | ||
а преобразовать имя переменной к адресу ячейки в памяти? да. в терминологии с++ - автоматическое. |
| Автор: Partizan 12.8.2008, 09:52 | ||
эээ...автоматическое? к сожалению не знаю такого термина.... что по-вашему при объявлении переменной int x с чем связывается? Добавлено через 5 минут и 52 секунды а вообще по хорошему автору надо курить полиморфизм...тогда не будет таких вопросов... |
| Автор: mes 12.8.2008, 10:37 | ||||||
1.
А вы не обратиле внимание , что в этой книжке не только о с++ пишется. также непонятно где Вы там Страуструпа нашли Примером динамического связывания в с++ является (реализованый разными стороними библиотеками) тип Variant. 2. Не в c++ делается примерно так: a=3; (сейчас у а тип инт) а = "строка"; (теперь тип строка) разновидностей и подходов много и зависит от реализации конкретного языка 3. пямять выделяется не под тип, а под переменную. 4. Как связан тип с инициализацией ? вот ограниченный пример динамического связывания
|
| Автор: Gunslinger 12.8.2008, 11:30 | ||||||||
в той книге написано, что кроме динамического связывания есть еще и автоматическое, а в с++ int x=2 - автоматическое. просто щас каша в голове, хотел как-то разграничить.
я бы покурил, только инфы на википедии мне не достаточно, а из книг я изучал с++ только по Уолтеру Савичу, там полиморфизм функций описан. Я так думаю, термин "связывание типов" - это описание какого-то процесса на уровне железа и двоичного кода. Только никак не могу понять какого.
с физическим адресом ячейки памяти.
обратил, но интересуюсь только с++. Про Страуструпа было в начале, вот и решил, что эту главу написал он.
я что-то пропустил? когда стали писать как в питоне? |
| Автор: cutwater 12.8.2008, 11:33 | ||
Я об этом уже говорил. Просто автор не понимает о чем пишет, почитайте Шилдта или Страуструпа. Там очень хорошо описаны полиморфизм и связывание. Автору так же смотреть мой пример выше. |
| Автор: mes 12.8.2008, 18:49 | ||||||
пропустили частицу "не" в начале цитаты.. ;)
в данном примере i и f занимают одну и туже физическую ячейку памяти (делает это структура union) , однако тип у обоих переменных разных . Тип - это проявление взаимодействия со значением. Некая сущность, которая определяет какие виды взаимодействия и каким образом подерживаются. |
| Автор: Gunslinger 13.8.2008, 20:22 | ||
т.е. должны быть проверки для того, чтобы это определить? Добавлено через 4 минуты и 14 секунд в смысле проверки - работа компилятора. |
| Автор: mes 14.8.2008, 14:10 | ||
точнее сказать не проверка, а выбор функции. Т.е вид взаимодействия с ячейкой (оно и есть выбор подходяшей реализации функции) осушествляется на основе типа значения. Например у нас есть функция print(). Для работы с разными типами мы перегружаем ее :
Добавлено через 1 минуту и 30 секунд в языках с динамическим типом переменых, выбор подходяшей функции (вышеразобранная ситуация) происходит не во время компиляции,а во время выполнения. |
| Автор: Gunslinger 15.8.2008, 15:25 | ||
меня интересовало связывание на уровне компилятора, а полиморфизм я считал только логической штукой для удобства программирования. так вот при чем здесь полиморфизм. |
| Автор: Partizan 15.8.2008, 16:58 | ||||
Gunslinger, полиморфизм как он есть возможен как раз благодаря позднему связыванию. |
| Автор: mes 16.8.2008, 00:04 | ||||
обычно под словом "позднее связывaние" подразумевает связывание в режиме выполнения... полиморфизм бывает статический и динамический. Динамический выполняется в рантайм, а статический на этапе компиляции(т.е на при раннем связывании) Добавлено через 1 минуту и 52 секунды
полиморфизм эта одна одно из проявлений связывания типов. |