Function result 
Author Message
 Function result

Hi there, I've a problem:

TYPE
    TKBDKey=Record
        ScanCode,Prefix:Byte;
        Status:Word;
    END;

FUNCTION KBDReadKey:LongInt;
ASSEMBLER;
ASM
    XOR  AX,AX
    MOV  DX,AX
END;

VAR
    Key:TKBDKey;{This must stay}
BEGIN
    Key:=TKBDKey(KBDReadKey);{This is what I want, but it can't this way}
END.

Anybody has a solution?




Wed, 18 Jun 1902 08:00:00 GMT  
 Function result



Quote:
>Hi there, I've a problem:

>TYPE
>    TKBDKey=Record
>        ScanCode,Prefix:Byte;
>        Status:Word;
>    END;

>FUNCTION KBDReadKey:LongInt;
>ASSEMBLER;
>ASM
>    XOR  AX,AX
>    MOV  DX,AX
>END;

>VAR
>    Key:TKBDKey;{This must stay}
>BEGIN
>    Key:=TKBDKey(KBDReadKey);{This is what I want, but it can't this way}
>END.

>Anybody has a solution?



You try to cast a longint onto a record type, using a 'value
typecast', but this is only allowed if both types are either ordinal
types or pointer types (BP7 Language Guide, page 77).

For this purpose, however, you can use a 'variable typecast' (BP7
Language Guide, page 57), as shown below.

VAR
    Key:TKBDKey;
    dmy: longint;
BEGIN
    dmy:= KBDReadKey;
    Key:= TKBDKey(dmy);
END.

--
J.R. Ferguson, Amsterdam, The Netherlands



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result


Wed, 18 Jun 1902 08:00:00 GMT  
 Function result



Quote:


> >Hi there, I've a problem:

> First, this is not BASIC. There is no need to shout. Just use lower
> case.

Using uppercase for all keywords was very common in the
70s and 80s.  I still think using uppercase for ALL keywords
makes the structure of a program stand out.  "Shouting"
for using all uppercase is a recent (like the last few years)
invention.  Using uppercase keywords in source code is not
shouting -- it's a good structured, programming practice.

Besides, you don't see all that IDE special
color coding here on the Internet do you?  It
only works inside the Borland IDE!  Uppercase
works everywhere ASCII is welcome.

efg
_____________________________________

MedTech Research Corporation
Lenexa, KS  66219  USA                    



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result


Wed, 18 Jun 1902 08:00:00 GMT  
 Function result



Quote:

>A more elegant way would be to make KBDReadkey a procedure.

The way I tend to do these things is with absolute vars:

VAR
    Key:TKBDKey;
    Key_longint : longint absolute Key;    {Key_longint shares same
                                            memory as Key}
BEGIN
    Key_longint := KBDReadKey;
    {Key now has the cast value in it automatically}
END.

I mention this because I'm curious to know whether this is considered a
"good" solution or not.

--

2M_ControlWare, Yaxley, Peterborough, ENGLAND.



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result


Quote:

> The way I tend to do these things is with absolute vars:

> VAR
>     Key:TKBDKey;
>     Key_longint : longint absolute Key;    {Key_longint shares same
>                                             memory as Key}
> I mention this because I'm curious to know whether this is considered a
> "good" solution or not.

I'm afraid I missed the earlier messages so I don't know how big tKbdKey
is. Is it as big as a LongInt? 'Cos if not you have to be careful.

For example, the program

var
  a : byte;
  b : byte;
  l : LongInt absolute a;

Begin
  a := 1;
  b := 2;
  l := -1;
  writeln(b);
End.

writes 255 - the variable L, being larger than the variable a which it
overwrites, clobbers whatever happens to be next in memory, which is
variable b. I tried it with b declared _after_ l as well and the effect is
the same.

In other words, if you really want to use Absolute, please only overlay a
variable with something the same size or smaller.

Frank



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result

Quote:



> >A more elegant way would be to make KBDReadkey a procedure.

> The way I tend to do these things is with absolute vars:

> VAR
>     Key:TKBDKey;
>     Key_longint : longint absolute Key;    {Key_longint shares same
>                                             memory as Key}
> BEGIN
>     Key_longint := KBDReadKey;
>     {Key now has the cast value in it automatically}
> END.

> I mention this because I'm curious to know whether this is considered a
> "good" solution or not.

Just to show that there's even more ways to accomplish it, I would use
something like:

type
  TKBDKey=Record
    case integer of
      0 : (ScanCode,Prefix:Byte;
           Status:Word);
      1 : (long : longint);
  end;

var
  Key:TKBDKey;

begin
  Key.long := KBDReadKey;
  {Key now has the cast value in it automatically}
end.

They're both equivalent.  For simple records, I find variants easier,
and less effort.  I use absolutes with more complex structures, or when
the representation of the data is supposed to vastly differ.

Quote:
> --

> 2M_ControlWare, Yaxley, Peterborough, ENGLAND.

--
Scott Earnest        | We now return you to our regularly |



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result

Quote:



>>Hi there, I've a problem:

>First, this is not BASIC. There is no need to shout. Just use lower
>case.

This is copied directly from my source files and I'm not going to modify it just becomes it's not
regular! Besides, this isn't that much uppercase (my assembler files are entirely uppercase).

Quote:
>>TYPE
>>    TKBDKey=Record
>>        ScanCode,Prefix:Byte;
>>        Status:Word;
>>    END;

>>FUNCTION KBDReadKey:LongInt;
>>ASSEMBLER;
>>ASM
>>    XOR  AX,AX
>>    MOV  DX,AX
>>END;

>>VAR
>>    Key:TKBDKey;{This must stay}
>>BEGIN
>>    Key:=TKBDKey(KBDReadKey);{This is what I want, but it can't this way}
>>END.

>>Anybody has a solution?
>There are two different kinds of typecasts: value and variable.
>They look similar and are thus easy to confuse. In value
>typecast the value to be typecasted and the type to which it is
>casted have to be either ordinal types or pointers. In value typecast
>the sizes of the types can be different in which case the value is kept
>(if possible). In variable typecast the one can only typecast a variable
>and the size of the types have to be same.
>Your typecast cannot be a value typecast as TKBDKey is neither ordinal
>or pointer. It cannot be a variable typecast as KBDReadKey is not a
>variable. So it gives an error. It might be better if a different syntax
>was used for the different typecasts. In that case they would not be
>confused so easily.
>As for solution, typecast the variable, i.e. Key.
>  longint(key):=KBDReadKey;

This is a good solution, thanks.

Quote:
>A more elegant way would be to make KBDReadkey a procedure.
>procedure KBDReadKey(var res:TKBDKey);
>ASSEMBLER;
>ASM
>    les di,res
>    XOR  AX,AX
>    mov  es:[di],ax
>    mov  es:[di+2],ax
>END;

This is a little bit faster and smaller:

PROCEDURE KBDReadKey(VAR Key:TKBDKey);
ASSEMBLER;
ASM
        LES  DI,Key
        DB  $66
        XOR  AX,AX              ;XOR  EAX,EAX
        DB  $66
        MOV  ES:[DI],AX ;MOV  ES:[DI],EAX
END;

But I prefer the function, it's again smaller and one can do with the result what he wants, e. g.
ignore. (Wait for a key).




Wed, 18 Jun 1902 08:00:00 GMT  
 Function result



Quote:

>I'm afraid I missed the earlier messages so I don't know how big tKbdKey
>is. Is it as big as a LongInt? 'Cos if not you have to be careful.

Same size as.

Quote:
>writes 255 - the variable L, being larger than the variable a which it
>overwrites, clobbers whatever happens to be next in memory, which is
>variable b. I tried it with b declared _after_ l as well and the effect is
>the same.

As it should be, if you do things like this. Beware that longint is
three bytes, not two, so that it would also be overwriting whatever else
followed in memory. I can't remember exactly how BP sets up the
vaiables; I would guess that in your example you'd be overwriting unused
stack space and not do any harm (although hardly a good idea!)

Using "absolute" requires that you are absolutely (sic) sure about what
you are doing.
--

2M_ControlWare, Yaxley, Peterborough, ENGLAND.



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result



Quote:
>Just to show that there's even more ways to accomplish it, I would use
>something like:

Now that I think about it, yes this is a much better solution than the
one I posted. I also do this quite a lot, and I like being able to use
both formats because sometimes one is more appropriate than the other,
but your method was a safer one to suggest here.

--

2M_ControlWare, Yaxley, Peterborough, ENGLAND.



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result

On Tue, 21 Oct 1997 12:51:18 +0100, Mark Rogers

Quote:

>The way I tend to do these things is with absolute vars:

>VAR
>    Key:TKBDKey;
>    Key_longint : longint absolute Key;    {Key_longint shares same
>                                            memory as Key}
>BEGIN
>    Key_longint := KBDReadKey;
>    {Key now has the cast value in it automatically}
>END.

>I mention this because I'm curious to know whether this is considered a
>"good" solution or not.

Who cares about "good" or "bad" - if it is correct ?

I prefer the slightly more structured approach:

type
  tKey = record
    case integer of
    0 : ( Key:TKBDKey);
    1 : ( Key_Longint:longint);
  end;

Regards
Horst



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result

On Tue, 21 Oct 1997 18:08:00 -0400, Scott Earnest

Quote:




>> >A more elegant way would be to make KBDReadkey a procedure.

>> The way I tend to do these things is with absolute vars:

>> VAR
>>     Key:TKBDKey;
>>     Key_longint : longint absolute Key;    {Key_longint shares same
>>                                             memory as Key}
>> BEGIN
>>     Key_longint := KBDReadKey;
>>     {Key now has the cast value in it automatically}
>> END.

>> I mention this because I'm curious to know whether this is considered a
>> "good" solution or not.

>Just to show that there's even more ways to accomplish it, I would use
>something like:

>type
>  TKBDKey=Record
>    case integer of
>      0 : (ScanCode,Prefix:Byte;
>           Status:Word);
>      1 : (long : longint);
>  end;

>var
>  Key:TKBDKey;

>begin
>  Key.long := KBDReadKey;
>  {Key now has the cast value in it automatically}
>end.

>They're both equivalent.  For simple records, I find variants easier,
>and less effort.  I use absolutes with more complex structures, or when
>the representation of the data is supposed to vastly differ.

>> --

>> 2M_ControlWare, Yaxley, Peterborough, ENGLAND.

Of course, there is one strong argument for the variant record
solution: it is standard Pascal and therefore portable to other
compilers.

Bob Ferguson.

--
J.R. Ferguson, Amsterdam, The Netherlands



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result



Quote:

>Who cares about "good" or "bad" - if it is correct ?

As pointed out by somebody else, using the approach I suggested requires
that whoever uses it be careful of the consequences (ie by making sure
that the two types tied together by "absolute" are of the same size).
That probably makes it a "bad" solution for unwary programmers.

A solution which "works" may be easily breakable by changing something
apparantly unrelated elsewhere. Changing the size of the original record
in this thread could conceivably result in strange behaviour from the
routine which referenced a variable of that type via the absolute
method. It is never a bad idea to think of these things in advance.

--

2M_ControlWare, Yaxley, Peterborough, ENGLAND.



Wed, 18 Jun 1902 08:00:00 GMT  
 Function result

Quote:

>On Tue, 21 Oct 1997 12:51:18 +0100, Mark Rogers

>>The way I tend to do these things is with absolute vars:

>>VAR
>>    Key:TKBDKey;
>>    Key_longint : longint absolute Key;    {Key_longint shares same
>>                                            memory as Key}
>>BEGIN
>>    Key_longint := KBDReadKey;
>>    {Key now has the cast value in it automatically}
>>END.

>>I mention this because I'm curious to know whether this is considered a
>>"good" solution or not.
>Who cares about "good" or "bad" - if it is correct ?

Maybe bad code has more chance of `hidden' bugs. They're very hard to find!

Quote:
>I prefer the slightly more structured approach:
>type
>  tKey = record
>    case integer of
>    0 : ( Key:TKBDKey);
>    1 : ( Key_Longint:longint);
>  end;
>Regards
>Horst




Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 21 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Function result type

2. function resulting in array?

3. function result type

4. TQuery as a result of a function

5. Turbo Pascal for Windows and Round function and randomize function

6. why define a function w/in another function?

7. functions as function

8. functions as function

9. BP7: Function of type function

10. Pass Functions into Function

11. Pass Functions into Function?

12. Working with TQuery Result Set

 

 
Powered by phpBB® Forum Software