6

Today one of my friend ask me about below code :

var
  a: Integer;
begin
  ShowMessage(IntToStr(a));
end;

This is local variable and not been initialized , ok ?

Put code in OnClick event of a button component and then run code in three diffrent ways below :

  1. Click on the button and see result , result = 1635841
  2. Press Enter key and see result , result = 1
  3. Press Space key and see result , reuslt = 1636097

I test code in two diffrent computer & see same result , any idea about this ?

Warren P
  • 65,725
  • 40
  • 181
  • 316
Mojtaba Tajik
  • 1,725
  • 16
  • 34
  • On my machine, I get different results. I also get different results every time I run the program. (However, I see no difference depending on how the button is clicked.) – Andreas Rejbrand Jul 23 '11 at 14:33
  • What i get on pc is 5734816 which is value stored in EBX register )) – Boris Treukhov Jul 23 '11 at 14:36
  • 8
    Upvoted because obviously this is a new person just learning Delphi. Not sure why the downvotes? Welcome to SO, Geek. – Warren P Jul 23 '11 at 15:10

3 Answers3

10

Since the variable is not initialized, its value can be anything. Since your result is 'something', there is nothing unusual at all going on here.

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • 1
    +1 One interesting thing is that it sometimes even goes to strings http://stackoverflow.com/questions/3250827/initialise-string-function-result – Boris Treukhov Jul 23 '11 at 20:48
  • No @Boris, the string-result problem is a different problem. String results are actually initialized by the calling functions, not the called function, that's why they appear to retain there value. – Cosmin Prund Jul 24 '11 at 05:56
  • 1
    @Cosmin String results are instancied, not initialized by the calling function. If you call several times a function with a result string which is not assigned inside the function, if you change the content between two calls, the content will remain untouched: the string instance is instantiated, first filled with '', but will not be reset to '' for each function call. Only the `out aText: string;` parameter will clear the string before each call. – Arnaud Bouchez Jul 24 '11 at 06:38
  • @A.Bouchez, The result *is* initialized by the calling function, look at the assembler prologue of the *calling* function. I'm not saying the result is initialized before every call, because it's not, it's only initialized once when the calling function is entered. But if no initialization took place, you'd expect Access Violations to happen quite often while assigning the string result of functions! – Cosmin Prund Jul 24 '11 at 06:54
  • 1
    @Cosmin You're perfectly right - I was just afraid that your comment could be misunderstood. I made a distinction between "instancied" (meaning the auto-generated asm prefix `PString(aString)^ := nil` during stack allocation), and "initialized" (i.e. `aString := ''`). You should have written "String results are actually initialized by the calling functions" **during its stack initialization of the local variables, and not each time the sub-function is called, or you'll have to use the `out` keyword**. Or something like that. – Arnaud Bouchez Jul 24 '11 at 14:38
  • Anyway I'll better stick to explicit initialization of string results as I don't expect the users of my string returning methods to be Delphi SO experts who will analyze my source code every time deciding if they should reset their variables or not. ;-) – Boris Treukhov Jul 24 '11 at 17:23
2
procedure TForm1.Button1Click(Sender: TObject);
var
  a: Integer;
begin
    ShowMessage(IntToStr(Integer(a)));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 ShowMessage(IntToStr(Integer(Pointer(TButtonControl(Button1)))));
end;

on my machine this code produces same message as compiler uses ebx register for a variable, while TButtonControl.WndProc uses ebx to store pointer to Self(as EAX will be overwritten after WinAPI function calls from TbuttonControl.WndProc) which is button1 before calling the actual handler Button1Click. So alas, on Delphi 2007 message text is too predictable.

[edited] You can see what's happening inside VCL while debugging if you turn on Use debug DCUs option in your project compiler options Compiler->Debugging->Use debug DCUs.

Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91
  • 2
    Do not add the Delphi source directory to your compiler search path. You run the risk of Delphi recompiling those units. To debug through the VCL units, turn on the "debug DCUs" option, which adds the debug-DCU folder to the search path; that folder contains no source code. – Rob Kennedy Jul 23 '11 at 19:14
  • fixed - it seems that I step on the same rake now and then – Boris Treukhov Jul 23 '11 at 19:49
1

See this similar Stackoverflow question.

In Delphi local variables are not initialised by default. The programmer is responsible for that and should always set a value before reading it. The value of an unitialised variable depends on the content of the actual allocated memory cells used for that variable. So any value is possible here.

Community
  • 1
  • 1
vanje
  • 10,180
  • 2
  • 31
  • 47
  • i know this ! and i say in my first post that @"This is local variable and not been initialized " ! – Mojtaba Tajik Jul 23 '11 at 15:22
  • 1
    Then what's the question here? On Delphi language level, all you have to know is that the value of an uninitialised variable is undefined. If you really want to know what's going on exactly you have to look at machine code level. But the generated code depends heavily on the compiler version and compiler flags (debug mode, optimization level, etc.). Usually the memory for local variables is allocated from the stack. And the stack grows and shrinks permanently during program execution so fresh local variables can contain any value, maybe a former used return address, but who cares? – vanje Jul 23 '11 at 15:53