Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Are you delphi pointer pro?

  1. #1

    Are you delphi pointer pro?

    It has been very quiet here lately, so I posted a little exercise for you.
    Here is the question: What are those 6 ShowMessages displaying?
    No testing with Delphi allowed.

    Code:
    function Get1(var X): Integer;
    var
      L: Integer absolute X;
    begin
      Result := PInteger(L-4)^;
    end;
    
    function Get2(var X): Integer;
    asm
      mov EAX, [EAX-4]
    end;
    
    procedure TForm1.Button4Click(Sender: TObject);
    type
      PIntArray = ^TIntArray;
      TIntArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer;
    var
      pInt: ^Integer;
      PTest: array of Integer;
    begin
      SetLength(PTest, 5);
      PTest[0] := 57;PTest[1] := 1;PTest[2] := 2;PTest[3] := 3;PTest[4] := 4;
      pInt := @PTest[0];
      Inc(pInt, 3);
      ShowMessage(IntToStr(pInt^));                // 1
      Dec(pInt, 4);
      ShowMessage(IntToStr(pInt^));                // 2
      ShowMessage(IntToStr(Get2(PTest[0])));       // 3
      ShowMessage(IntToStr(Get1((@PTest)^)));      // 4
      pInt := @PTest;
      pInt := Pointer(pInt^);
      ShowMessage(IntToStr(pInt^));                // 5
      ShowMessage(IntToStr(PIntArray(pInt)[2]));   // 6
    end;

  2. #2

    Are you delphi pointer pro?

    This is not about pointers, but ...
    Exrecise no 2:

    Code:
    procedure TForm1.Button6Click(Sender: TObject);
    var
      a, b: Integer;
    begin
      a := 345;
      b := 7690;
      ShowMessage(IntToStr(a)+':'+IntToStr(b));  // 1
      a := a xor b;
      b := b xor a;
      a := a xor b;
      ShowMessage(IntToStr(a)+':'+IntToStr(b));  // 2
      a := a + b;
      b := a - b;
      a := a - b;
      ShowMessage(IntToStr(a)+':'+IntToStr(b));  // 3
    end;
    Siim

  3. #3

    Are you delphi pointer pro?

    For the second one:
    345:7690
    7690:345
    345:7690
    Just looking at the first one makes my eyes hurt, so I?¢_Tll skip it for today

  4. #4

    Are you delphi pointer pro?

    Okay, for the first one I'm going to go with:

    256
    14592
    -1
    -1
    1
    2

    Chances are most - if not all - of those are wrong, though... :scratch:

    Personally, I think anyone writing code like that would get fired pretty soon!
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  5. #5

    Are you delphi pointer pro?

    I pasted the code into Delphi... It seems the actual results are:

    3
    5
    5
    5
    57
    2

    Well, at least I got one right! ops:
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  6. #6

    Are you delphi pointer pro?

    Quote Originally Posted by Useless Hacker
    I pasted the code into Delphi... It seems the actual results are:

    3
    5
    5
    5
    57
    2

    Well, at least I got one right! ops:
    Heh, at least you gave answers. I got most of them but since I didn't post it then nobody would believe me!

    Number 1: the pointer is pointed to the first element of the 5-element array. It's then inc'd on 3 places, meaning it goes to ptest[3] instead of ptest[0]. Ptest[3] = 3

    Number 2: the pointer is dec'd four positions. This moves it before the first actual element, onto the internal array length int. This you might remember if you ever used Delphi 1 and its strings (my_string[0] there being the length of the array, later replaced with Length and SetLength, I believe, in Delphi 2).

    Number 3: the parameter to the func will be passed in the accumulator (EAX). The value [EAX - 4] means "dereference the address 4 earlier (sizeof integer) than the given variable," which would be the value before the first array element. At least, if I remember my asm right. Again, the size of the array. From the help files: "The built-in assembler treats var parameters as a 32-bit pointers."

    EDIT: It's also worth mentioning that the results of functions are put into the accumulator (al, ax or eax)...

    Number 4: same deally here - the absolute directive (deprecated, IIRC) places the variable at the same spot in memory as the given var -- so it would be the same address as the untyped parameter. And I believe it works much the same as the previous asm routine.

    Number 5: I admit that I was initially a little stumped by the fancy footwork here. Here's what I thought happens...

    pInt := @PTest;
    pInt := Pointer(pInt^);

    Dynamic arrays are dynamically allocated, hence they're pointers with fancy compiler support. pInt is pointed to a pointer's (the array's) address-of, then dereferenced (the original array address again) and cast as a pointer. So, it's still pointing to the first element of the array, I believe, when next dereferenced (ptest[0] = 57).

    Number 6: not exactly a difficult one here. Just treat the pint pointer as a pointer to an array of integers starting at the same pos as the first element of the dynamic array. So return the value of ptest[2], in other words, which is 2.

    Loved these puzzles. If I got any of the above wrong then please let me know! Got any more of these puzzles for us (or maybe I'll try to think up one...)?
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  7. #7

    Are you delphi pointer pro?

    Quote Originally Posted by Alimonster
    Number 1: the pointer is pointed to the first element of the 5-element array. It's then inc'd on 3 places, meaning it goes to ptest[3] instead of ptest[0]. Ptest[3] = 3

    Number 2: the pointer is dec'd four positions. This moves it before the first actual element, onto the internal array length int. This you might remember if you ever used Delphi 1 and its strings (my_string[0] there being the length of the array, later replaced with Length and SetLength, I believe, in Delphi 2).
    I had thought that Inc(pInt, 3) would increase the pointer by 3 bytes, and that Dec(pInt, 4) would decrease it by 4 bytes...

    I'm not quite sure how I got those minuses for 3 and 4 :?
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  8. #8

    Are you delphi pointer pro?

    Quote Originally Posted by Useless Hacker
    I had thought that Inc(pInt, 3) would increase the pointer by 3 bytes, and that Dec(pInt, 4) would decrease it by 4 bytes...
    but then again...
    Quote Originally Posted by (The person who wrote) the Delphi Help
    procedure Inc(var X [ ; N: Longint ] );

    Description

    In Delphi code, Inc adds one or N to the variable X.

    X is a variable of an ordinal type (including Int64), or a pointer type if the extended syntax is enabled.

    N is an integer-type expression.

    X increments by 1, or by N if N is specified; that is, Inc(X) corresponds to the statement X := X + 1, and Inc(X, N) corresponds to the statement X := X + N. However, Inc generates optimized code and is especially useful in tight loops.

    Note: If X is a pointer type, it increments X by N times the size of the type pointed to.
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  9. #9

    Are you delphi pointer pro?

    Very well explained Alimonster.
    Okay another puzzle...
    Exercise no 3:
    There may be more than one solution for this problem. And for some people the problem might be very easy to solve.
    A crazy programmer (me?!?) has design a component with eventhandler like this:
    Code:
      TOnChange = procedure&#40;var I&#58; Integer&#41;;
      TMyObject = class
        private
          FOnChange&#58; TOnChange;
        public
          property OnChange&#58; TOnChange read FOnChange write FOnChange;
      end;
    You want to keep your code object-oriented at all costs and you want to attach a method DoIt with this event so you do something like this:
    Code:
      TForm1 = class&#40;TForm&#41;
        procedure FormCreate&#40;Sender&#58; TObject&#41;;
      private
        &#123; Private declarations &#125;
        Obj&#58; TMyObject;
        procedure DoIt&#40;var I&#58; Integer&#41;;
      public
        &#123; Public declarations &#125;
      end;
    
    var
      Form1&#58; TForm1;
    
    implementation
    
    &#123;$R *.DFM&#125;
    
    &#123; TForm1 &#125;
    procedure TForm1.DoIt&#40;var I&#58; Integer&#41;;
    begin
      ShowMessage&#40;IntToStr&#40;I&#41;&#41;;
    end;
    
    procedure TForm1.FormCreate&#40;Sender&#58; TObject&#41;;
    begin
      Obj &#58;= TMyObject.Create;
      Obj.FOnChange &#58;= DoIt;
    end;
    Remember that you can't change anything that crazy programmer has already done (TOnChange is done by a crazy programmer) and you have to keep things object-oriented.
    The code above doesn't even compile. Your job is to fix it.

    Siim

  10. #10

    Are you delphi pointer pro?

    I am not quite sure what you want to happen, (and where we may change etc.) But if we may add, I'd just write an overload precedure for doit without parameters, and then it should compile.

    Ie.

    procedure TForm1.DoIt;
    begin
    ShowMessage('Nike!');
    end;


    But if I am not allowed to add even 'overload to his' DoIt(I:Integer) procedure... I dunno.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •