DEFфайл из примеров
Пример 3.10. DEF-файл из примеров кода VisualAge C++ V3.0
LIBRARY REXXUTIL INITINSTANCE LONGNAMES
PROTMODE
DESCRIPTION 'REXXUTIL Utilities - (c) Copyright IBM Corporation 1991'
DATA MULTIPLE NONSHARED STACKSIZE 32768
EXPORTS
SYSCLS = SysCls @1 SYSCURPOS = SysCurPos @2 SYSCURSTATE = SysCurState @3 SYSDRIVEINFO = SysDrivelnfo @4
SYSDRIVEMAP = SysDriveMap @5
SYSDROPF0NCS = SysDropFuncs @6
SYSFILEDELETE = SysFileDelete @7
SYSFILESEARCH = SysFileSearch @8
SYSFILETREE - SysFileTree @9
SYSGETMESSAGE = SysGetMessage 010
SYSINI = Syslni 011
SYSLOADFUNCS = SysLoadFuncs @12
SYSMKDIR = SysMkDir @13
SYSOS2VER = SysOS2Ver 014
SYSRMDIR = SysRmDir @15
SYSSEARCHPATH = SysSearchPath @16
SYSSLEEP = SysSleep @17
SYSTEMPFILENAME = SysTempFileName @18
SYSTEXTSCREENREAD = SysTextScreenRead @19
SYSTEXTSCREENSIZE = SysTextScreenSize La20
SYSGETEA = SysGetEA @21
SYSPUTEA = SysPutEA @22
SYSWAITNAMEDPIPE = SysWaitNamedPipe @23
DLL являются удобным средством разделения кода и создания отдельно загружаемых программных модулей, но их использование сопряжено с определенной проблемой, которая будет подробнее объясняться в разд. Разделяемые библиотеки. Забегая вперед, скажем, что концепция разделяемых DLL наиболее естественна в системах, где веб задачи используют единое адресное пространство — но при этом ошибка в любой из программ может привести к порче данных или кода другой задачи. Стандартный же способ борьбы с этой проблемой — выделение каждому процессу своего адресного пространства — значительно усложняет разделение кода.
Другая проблема, обусловленная широким использованием разделяемого кода, состоит в слежении за версией этого кода. Действительно, представим себе жизненную ситуацию: в системе одновременно загружены тридцать программ, использующие библиотеку LIBC.DLL. При этом десять из них разрабатывались и тестировались с версией 1.0 этой библиотеки, пять — с версией 1.5 и пятнадцать — с версией 1.5а. Понятно, что рассчитывать на устойчивую работу всех тридцати программ можно только при условии, что все три версии библиотеки полностью совместимы снизу вверх не только по набору вызовов и их параметров, но и по точной семантике каждого из этих вызовов. Последнее требование иногда формулируют как bug-for-bug compatibility (корректно перевести это словосочетание можно так: полная совместимость не только по спецификациям, но и по отклонениям от них).
Казалось бы, исправление ошибок должно лишь улучшать работу программ, использующих исправленный код. На практике же бывают ситуации, когда код основной программы содержит собственные обходные пути, компенсирующие ошибки в библиотеке. Эти обходы могут быть как внесены сознательно (когда поставщик библиотеки исправит, еще неизвестно, а программа нужна сейчас), так и получиться сами собой (арифметический знак, перепутанный четное число раз и т. д.). В этих случаях исправление ошибки может привести к труднопредсказуемым последствиям. Нельзя также забывать и о возможности внесения новых ошибок при исправлении старых, поэтому при разработке и эксплуатации сложных программных систем, необходимо тщательно следить за тем, что именно и где изменилось, а не просто фиксировать ошибки.
Требование "совместимости с точностью до ошибок" — это лишь полемически заостренная формулировка требования контролируемости поведения кода. Из вышеприведенных соображений понятно, что нарушения такой контролируемости представляют собой проблему, которая, не будучи так или иначе разрешена, может серьезно усложнить работу администраторов системы и приложений.