В очередной раз, «копаясь» во внутренностях Клары, обнаружил довольно неприятную ошибку порождаемую компилятором.
Map MyFunc(),*STRING End Str &STRING Code Str &= MyFunc() if ~(Str &= Null) then Message(Str). Return MyFunc Procedure Code Return Null
Стандартная, казалось-бы, ситуация.
Есть функция, которая возвращает указатель на строку. Неважно, как она формирует эту строку. Важно (ОЧЕНЬ!!!), что она может вернуть нулевой указатель, если, например, из-за ошибки она не смогла сформировать для возврата нужную строку. И в программе мы всегда можем после вызова данной функции проверить возвращаемый указатель на валидность (см. выше) и адекватно на него отреагировать. И, казалось-бы, вполне правильно было-бы в этой функции возвращать нулевой указатель, например, так:
if ErrorCode() then Return Null.
Но! Не тут-то было! К сожалению, в данном случае компилятор генерит код, который возвращает не 0, как должно быть, а совершенно случайное число, которое выбирает из неинициализированной области памяти на стеке! И данная ошибка имеет место быть ТОЛЬКО при возврате указателя на строку! Во всех остальных случаях генерится правильный код.
Т.е., если, например, функция возвращает указатель на файл, то вышеприведенный код вернет именно нулевую ссылку, которую потом можно спокойно сравнивать с Null.
А для функций, которые должны возвращать указатель на строку, для правильной работы необходимо возвращать Null не напрямую, а косвенно, через переменную:
MyFunc Procedure OutStr &STRING Code OutStr &= Null Return OutStr
Вот теперь все будет нормально работать!
P.S.
Писал ли кто под виндовой Кларой в 32-бит режиме процедурки на ее ассемблере? Никак не удается заставить ее генерить правильный код! Т.е., например, инструкция MOV AX,BX генерится как угодно!
То-же и с инструкциями типа MOV EAX,EBX.
Может есть какое средство, чтобы заставить Клару генерить правильный код из ASM-исходника ?!
Проблема именно с виндовой Кларой. Под досовой все нормально!
Или, возможно, кто подскажет, можно ли в исходнике на Кларином же С управлять регистрами? Т.е., можно ли выполнить, например, asm-инструкцию типа MOV SI,SP или ADD SP,SI
???