2

In Delphi we can do this:

 interface 
 var
   test: string = 'this is a test!'; { compiler accepts that }

But we can not do this:

 implementation
 procedure showTest;
 var
   internal_test1; { compiler accepts that }
   internal_test2: string = 'another test'; { compiler error }

I hope some user from Embarcadero could answer that. :-)

NaN
  • 8,596
  • 20
  • 79
  • 153
  • http://docwiki.embarcadero.com/RADStudio/XE4/en/Memory_Management_on_the_Win32_Platform – bummi Jun 25 '13 at 16:26
  • 1
    You simply can't. The compiler does not allow it. What more can anyone say about it? – Rudy Velthuis Jun 25 '13 at 16:34
  • 1
    And if one really wants consistency, at the expense of stepping off pure Pascal: http://wiki.oxygenelanguage.com/en/Minor_Language_Differences_compared_to_Delphi :) – lurker Jun 25 '13 at 16:39
  • I think this "anyone" could say WHY this rule... just like the title. The compiler did not invented this rule. – NaN Jun 25 '13 at 16:40
  • 4
    What more, @Rudy? Maybe someone has an idea of the technical history that lead to the apparent inconsistency, and would be willing to share that insight. Perhaps there's more to it than simply that the compiler writers didn't bother to implement such a feature. – Rob Kennedy Jun 25 '13 at 16:50
  • @RobKennedy Yes and... no. You know that the compiler already auto-generates zero-initialization code for some types of local variables. And that module could be relatively easily extended to assign all the pre-initialized variables as well. So in the end that is "didn't bother to implement" again. OTOH this question seems bad match for SO in my eyes, for it basically reads "read the mind of some guys that worked on the compiler for all those decades and tell me what they thought about". How can we know WHAT did they thought and even their full list? – Arioch 'The Jun 26 '13 at 22:34
  • 1
    @mbratch i guess Oxygene does not have special "typed constants" semantics. For Delphi having wildly different behavior for local variables depending whether they were declared after `var` or after `const` would be a great gotcha and mind screwer for novices :-) – Arioch 'The Jun 26 '13 at 22:37
  • 1
    @Arioch'The Every language, I suppose, has its idiosyncrasies. As others have mentioned, it would indeed interesting to know what the language designers were thinking. – lurker Jun 26 '13 at 22:40
  • 1
    @mbratch 1) Delphi is not "pure Pascal", not even close to it. 2) IF you meant "stepping off Delphi look and feel" then there is one more choice - just install `CodeTyphon` (http://pilotlogic.com) instead of `Oxygene` and you have almost Delphi syntax plus local variables. http://www.freepascal.org/docs-html/ref/refse22.html Works AT LEAST since year 2004: http://community.freepascal.org/bboards/message?message_id=148550&forum_id=24082 – Arioch 'The Jun 26 '13 at 22:42
  • @Arioch'The - nowhere in my comment did I say or intend to imply that Delphi was "pure Pascal". I merely referred to "every language". Delphi being a dialect of Pascal, if you will. Original Pascal doesn't even have objects/classes. – lurker Jun 26 '13 at 22:45
  • @mbratch since the topic starter asked about Delphi, then Delphi is what he should "step off" by switching to Oxygene, and that correlates to the quoted text in my eyes. Just so. – Arioch 'The Jun 26 '13 at 22:52
  • 1
    @Arioch'The once in this very SO site a Embarcadero programmer answered me a questions about Delphi. So why not? Have a litle faith in the force! – NaN Jun 27 '13 at 12:48
  • 1
    IMHO, this question IS very constructive by the fact it allow us to get perspective on how modern compilers should be build thinking about rapid application development, and how to cover the lack of features in the actual tools. – NaN Jun 28 '13 at 13:00
  • @RobKennedy: I could, but it would not matter much, would it? Global variables can come preloaded with values, directly in the .exe. This is not possible for local variables, which have to be set up each time the func is entered. Then there is the problem of semantics. Should the variable be re-inited each time the local frame is set up, or should it retain changes between calls? Such questions do not arise for global variables. If a local variable should retain its value between calls, then it is in fact global, like a writeable typed "constant". I did not say more because it doesn't matter. – Rudy Velthuis Jun 28 '13 at 21:57
  • @RobKennedy: and I am not an Embarcadero employee. – Rudy Velthuis Jun 28 '13 at 21:58
  • 3
    @Rudy, a few minutes after this question was asked, you clearly dismissed it: *X* is not allowed because the compiler doesn't allow *X*, and that's all there is to it. You asked "What more can anyone say?" as though to say, "No one can say anything more on this, so why even consider the question?" I dispute that attitude, though. There are non-tautological reasons for what the compiler supports, and it can be useful to understand them. And I know you don't work for Embarcadero; did someone say you did? – Rob Kennedy Jun 28 '13 at 22:25
  • 1
    @Rudy, There is a reason why I asked that question. It's not a stupid one. Be more precocious. In the Embarcadero site, it says there is no guarantee that if you do not initialize a integer it's value would be 0, or other type of variable. So you WILL change the value of them inside the method, but the first lines of it are always to initialize them. There should be a good reason why we can't do that here, but we can do that in other languages. Dot – NaN Jun 28 '13 at 23:50
  • I never said it was stupid. But we can only guess for the reasons and I didn't think it made sense to guess. – Rudy Velthuis Jun 29 '13 at 08:08

2 Answers2

9

Global variables' values are assigned from compile-time constant expressions, and they're stored in the program's data segment. That is, space for those variables is allocated physically in the EXE file, so when the OS loads the program, those variables are loaded implicitly. The compiler can ensure that those variables are initialized without executing any code at run time. It just stores their initial values in the EXE file.

Local variables, on the other hand, do not exist until run time. There is no physical space in the EXE that will always refer to those variables. To initialize them, the compiler would have to generate code to assign values to them.

Global variables can be initialized because it was a technically easy thing to implement in early compilers, and it's essentially a free feature at run time, requiring no execution of any instructions by the CPU.

If you want to initialize local variables, you're free to write the code yourself; that code can do exactly what any compiler-inserted code would do.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • You missed one more point. There is only one instance for global variable, but there may be a million of instances of a local variable. – Arioch 'The Jun 26 '13 at 22:26
  • However that is not so for typed `const` - the rather weird way to make state-full subroutine :-D – Arioch 'The Jun 26 '13 at 22:27
  • The "do not exist until run time" begs a question "so what? do allocate them at compile time and they would exist!". Why that was not possible ? Exactly because for every single "name" of local variable there may be a multitude of simultaneously living "bodies" of it. – Arioch 'The Jun 26 '13 at 22:30
  • 1
    This sounds like the same reason why [all constants are constant, but some are more constant than others](http://stackoverflow.com/questions/2714365/delphi-all-constants-are-constant-but-some-are-more-constant-than-others). – Ian Boyd Jun 27 '13 at 13:50
  • Yes, @Ian. Typed constants (whether writable or not) and global variables are stored in the same part of the EXE file, and they're initialized with the same technique. – Rob Kennedy Jun 27 '13 at 13:58
3

Niklaus Wirth was a Computer Scientist researching and teaching the design of Languages and Compilers. When he designed the Pascal Language and Compiler, some of his design goals were to make the compiler small fast and efficient, and to partition tasks so that the compiler did things that were easy for the compiler, and the programmer did things that were easy for the programmer.

In line with these goals, he designed a Single-Pass compiler, that only had to read the source code once, and understood everything the first time through. He also designed a compiler with a very simple state machine: everything is done in order, in correct order, only in correct order.

By doing so, he was able to easily get a very small, fast, efficient and correct compiler, in contrast to C compilers which were notoriously difficult, incorrect and inefficient, and FORTRAN compilers, which were slow and large.

Doing static constant allocation once, at the start of the program, is one of these design decisions that allows you to write a small, fast, efficient, correct compiler.

Decades ago, Borland wrote a Pascal compiler that was small, fast, efficient and correct, and it competed successfully again more expensive products from other companies (such as MS) that allowed out-of-order declarations and other generally useful and helpful options that made the compiler more slow and difficult, but made programming easier.

In other words, MS choose to partition the tasks between compiler and user differently than Borland/Wirth did.

And the MS Pascal compiler was dropped a very long time ago. But the Borland compiler continues as Delphi.

Computers are a lot faster now than they used to be, but the task of writing a small, fast, efficient, correct compiler remains the same. New features are not free. Adding complexity to compilation comes at a cost. Even a simple feature is messy if it has to be added as an exception to the way the whole compiler and language were designed right from the very beginning.

david
  • 2,435
  • 1
  • 21
  • 33