forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

FULL_UNDEF and single CHARACTER data (again!)

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Fri Oct 26, 2007 3:57 pm    Post subject: FULL_UNDEF and single CHARACTER data (again!) Reply with quote

A lot of my programming revolves around acquiring and processing images. Whilst I love /CHECKMATE, the FULL_UNDEF feature does mean that extra care needs to be taken when manipulating images pixel-by-pixel. FULL_UNDEF causes a run-time error on any attempt to make reference to a single byte of memory with value 0x80. This is vexing, because once you get down to single-byte image data, 0x80 is a perfectly reasonable value that is liable to be sprinkled liberally throughout most images with mid-range pixel values. I have posted about this before.

A little while ago, I thought I had come up with a general-purpose solution. Isolate the code that accesses the single-byte data in a module, and compile it with /DEBUG, then link that module with all the other code compiled with /CHECKMATE.

The following code illustrates that this is not the end of the story. The program shows four different examples of trying to put 0x80 somewhere, and four different examples of trying to get it back again, using a module compiled with /DEBUG.

The first half of the code shows that putting 0x80 into memory can be achieved with the module approach. Example 3 shows a curious anomaly that, bearing example 2 in mind, I definitely do not understand. It does prove, however, that it is possible, in CHECKMATE-compiled code, to put 0x80 into a memory location associated with a single-character variable without resorting to the module approach.

The second half of the code, on the other hand, shows that getting 0x80 out of memory and into a "naked" single-character variable is not so easy, even with the module approach. I definitely do not understand why example 6 does not work, since the reference to 0x80 takes place within the DEBUG-compiled module. On the other hand, examples 7 and 8 show that it is no problem at all to get 0x80 out of memory in an "intermediate" capacity (albeit example 8 shows that even FTN95 is getting a little confused).

The saving grace, of course, is that I am never interested in single-character values other than as code for integers in the range 0-255, so I have never yet found a need for them as naked single characters, only as intermediates that can be nested away ... on the other hand, I am not a fan of nesting expressions, so I'd like to be able to define single-character variables, certainly during development (not least because, from time to time, I have known FTN95 to choke on nesting that should be no problem, particularly LOGICAL-based nesting).

Can anyone explain why example 3 coerces FTN95 into doing something apparently impossible? Or why example 6 fails to get it to do something apparently possible?

Paul, can you add the false warning provoked by example 8 to your list of things to attend to at some point, please?

Andy
-----------------------------------------
program uncharacteristic
use core_manipulation
character chai, chao
integer i, ptr, ichao

ptr = loc (chai)

!PUTting 0x80 somewhere is not too difficult

!1 naked 0x80 causes FULL_UNDEF error, reasonably enough
!1 chai = char (128) !

!2 ... and the same here
!2 ccore1 (ptr) = char (128)

!3 curiously, this near-naked 0x80 does NOT cause a problem!?
!3 do i = 128,128
!3 chai = char (i)
!3 end do

!4 this line PUTs a naked 0x80 where it is wanted by stealth
!4 (PROVIDED putchar is compiled only with DEBUG and not CHECKMATE)
call putchar (ptr, char (128))

!GETting a naked 0x80 from somewhere appears to be impossible

!5 causes FULL_UNDEF error
!5 chao = ccore1 (ptr)

!6 causes FULL_UNDEF error
!6 (even when getchar is compiled with DEBUG rather than CHECKMATE)!?
!6 chao = getchar (ptr)

!7 does not cause FULL_UNDEF error
!7 ichao = ichar (getchar (ptr))

!8 even this does not cause FULL_UNDEF error!?
!8 (but it does cause an erroneous warning #362)
! ichao = ichar (ccore1 (ptr))

stop
end program uncha
Back to top
View user's profile Send private message Send e-mail
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7925
Location: Salford, UK

PostPosted: Mon Oct 29, 2007 8:05 pm    Post subject: Reply with quote

As you will probably be aware, FTN95 uses 0x80 to represent an undefined character under /CHECKMATE (i.e. /FULL_UNDEF).

The checking normally takes place at runtime in code compiled using /CHECKMATE. This involves calls to one of a number of checking routines that are in salflibc.dll.

If you step into the code using the debugger and press F11 to view the assembly code then you will be able to find the exact point where the call is made and the failure is reported. This will give you an indication of how the checking is implemented.

Naturally the whole thing gets rather tricky if you need to use the character with value 0x80.

Do I need the code for your module to take this any further?

I can see the false warning you mentioned.
Back to top
View user's profile Send private message AIM Address
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Tue Oct 30, 2007 12:20 pm    Post subject: Reply with quote

Hi Paul,

Thanks for replying. Yes, you need the module code. I was convinced I had pasted it after the main program (I certainly intended to) but it seems not Embarassed Here it is, small but perfectly-formed:

module core_manipulation
contains
!------------------------------------------------
character function getchar (ptr)
integer ptr
getchar = ccore1 (ptr)
end function getchar
!------------------------------------------------
subroutine putchar (ptr, chi)
integer ptr
character chi
ccore1 (ptr) = chi
end subroutine putchar
!------------------------------------------------
end module core_manipulation
Back to top
View user's profile Send private message Send e-mail
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7925
Location: Salford, UK

PostPosted: Tue Oct 30, 2007 10:30 pm    Post subject: Reply with quote

I can now verify your results but I don't know where to go from here.
In each case you can see the call that is doing the checking from the explist.

Presumably you don't want us to make it fail in the odd cases you have got it to work.

Can you pick out one case and say what you would prefer to happen?
Not that I can promise to deliver.
Back to top
View user's profile Send private message AIM Address
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Wed Oct 31, 2007 10:57 am    Post subject: Reply with quote

Hi Paul,

Sorry, my code ended up much too "discursive". The example I would like to work is #6, so that the approach (of wrapping ccore1 in routines in a DEBUG-compiled module) works whether I'm setting or getting a character. It seems to me that if one works, so should the other.

I tried viewing the assembler code by pressing F11, but I am afraid I am none the wiser as to what is happening (I don't know what you mean by explist).

I appreciate you may not be able to make it happen - if I understood assembler better, maybe I would see that I am trying to do something impossible.

Andy
Back to top
View user's profile Send private message Send e-mail
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7925
Location: Salford, UK

PostPosted: Fri Nov 02, 2007 4:26 pm    Post subject: Reply with quote

The assignment in

chao = getchar (ptr)

results in a call to __CCOPY_U and this includes the FULL_UNDEF checking.

The trick is to do the assignment in a non FULL_UNDEF context.

call getchar1(chao, ptr)

where getchar1 does the assignment and is in your "unchecked" module.
Back to top
View user's profile Send private message AIM Address
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Fri Nov 02, 2007 6:44 pm    Post subject: Reply with quote

Aha! Easy when you know how.

For some reason, I had got into a mindset that said SETting = call to a subroutine, and GETting = result from a function.

I still think it's the natural way to do it. A SET is an "input" process; there's no natural output from it, and that indicates subroutine rather than function. Whereas a GET is inherently an "output" process, so it is natural to implement it as a function. But as you point out, there's more than one way to skin a GET Laughing

Thanks, Paul.

Andy
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group