Recent

Author Topic: Trivial question about global vatiables  (Read 1776 times)

simsee

  • Full Member
  • ***
  • Posts: 184
Trivial question about global vatiables
« on: February 21, 2021, 08:22:09 pm »
I apologize in advance for the trivial question...

According to following wiki https://wiki.freepascal.org/Global_variables and to my knowledge, a variable declared in a var section prior any other nested block in a program is global. So why in the following program gives the following error: unit1.pas(16,3) Error: Identifier not found "X" ??

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses Unit1;
  4.  
  5. var
  6.   X : integer;
  7.  
  8. begin
  9. end.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. procedure Proc;
  11.  
  12. implementation
  13.  
  14. procedure Proc;
  15. begin
  16.   X:=3;
  17. end;
  18.  
  19. end.



Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Trivial question about global vatiables
« Reply #1 on: February 21, 2021, 08:49:48 pm »
In Pascal, everything must be declared before it is used. In your example, Unit1 knows nothing about main project file, where X is declared.
Solution can be to create the third unit with variable X and add this unit to uses sections of both Project1 and Unit1.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

simsee

  • Full Member
  • ***
  • Posts: 184
Re: Trivial question about global vatiables
« Reply #2 on: February 21, 2021, 08:56:09 pm »
I suspected it was a consequence of the "declare before using" principle.  However this means that the wiki is incorrect.  It also follows that the program module cannot contain declarations of global variables.  Correct?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9857
  • Debugger - SynEdit - and more
    • wiki
Re: Trivial question about global vatiables
« Reply #3 on: February 21, 2021, 09:02:17 pm »
I suspected it was a consequence of the "declare before using" principle.  However this means that the wiki is incorrect.  It also follows that the program module cannot contain declarations of global variables.  Correct?

The question is how you interpret "global".
The variable exists during the entire run time of the program. => so it is global.

But, it is not globally accessible.
There are still scoping rules from where you can see (access) the variable.


If you indeed need a var that is accessible from everywhere (ignoring any design question that may rise), then you need to put it into a  unit (in the interface part), and use that unit in every other unit.
As soon as you use the unit with the var, it will be visible.

=> Same but bit more complex if you use packages.


simsee

  • Full Member
  • ***
  • Posts: 184
Re: Trivial question about global vatiables
« Reply #4 on: February 21, 2021, 09:32:21 pm »
Thanks for the clarifications. 

I'm aware of the drawbacks of global variables from a software engineering perspective, especially the unwanted coupling between modules.

Returning to the question, generally 'global variable' means variable with a global scope. Often this means that its life time coincides with the program run time. 

However I conclude that a globally scoped variable cannot be declared in the program module.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9857
  • Debugger - SynEdit - and more
    • wiki
Re: Trivial question about global vatiables
« Reply #5 on: February 21, 2021, 09:56:58 pm »
global scope. Often this means that its life time coincides with the program run time. 
"Existence/Lifetime" Scope: yes
"Visibility Scope": no

Sounds  confusing?

Well existence means that there is a fixed place in memory where the variable exists.
It is there from the start to the end of your apps runtime.

Visibility means that accessing that memory via the "identifier" (i.e. "var Foo: integer;" => ident = Foo) is not always possible.

The name may be out of scope. The value exists.
Had you taken the address of the value, you could do "PInteger(Addr)^"

Quote
However I conclude that a globally scoped variable cannot be declared in the program module.

That comes down to how you read "must be declared before being used"

True your app logically starts at the start of the "program" module.
But for the compiler each unit is a container of its own, where scope starts all over again.

The compiler can (pre-) compile any unit, and later use it in your program.

If your unit (or program) does "uses XYZ" then it imports XYZ, and things declared in (the interface section of) XYZ will come into scope.

The other way round, if your unit is *used* by another unit (or by the program) , it knows nothing about the "entity that uses it".

-----------
anyway as I said
Quote
unit MyGlobalVars;
interface
var Global1: integer;
implementation
end.

and in any other unit and in your program do "uses MyGlobalVars" => and you got your global
« Last Edit: February 21, 2021, 10:06:00 pm by Martin_fr »

simsee

  • Full Member
  • ***
  • Posts: 184
Re: Trivial question about global vatiables
« Reply #6 on: February 22, 2021, 12:33:25 am »
Excellent explanation. Thanks so much.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6683
Re: Trivial question about global vatiables
« Reply #7 on: February 23, 2021, 09:08:45 pm »
Martin in particular has given you chapter and verse on this, but the easy way to actually fix your problem is to pass x to Proc() as a parameter.

There are occasions where you want to do this, particularly if you want to use %file% in the main (program) unit in order to establish an imutable project name, which will later be used when looking for a configuration file.

Another valid use case is when you've got several different main program implementations, e.g. a text-only one written as a console program and a GUI one as an alternative. In each of those you've got a procedure for displaying messages (e.g. to the console or to a memo on a form), unless you pass that procedure as a parameter to your common backend it will be an in-scope global but won't actually be visible.

MarkMLl

MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 4015
Re: Trivial question about global vatiables
« Reply #8 on: February 24, 2021, 12:29:29 pm »
I suspected it was a consequence of the "declare before using" principle.  However this means that the wiki is incorrect.  It also follows that the program module cannot contain declarations of global variables.  Correct?
It's conceptually correct but, there is a way to declare variables in the program module and make them available in units used by the program, effectively and selectively turning them into global variables. 

The solution is found in the post of this thread https://forum.lazarus.freepascal.org/index.php/topic,45707.msg323530.html#msg323530

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6683
Re: Trivial question about global vatiables
« Reply #9 on: February 24, 2021, 12:52:28 pm »
I suspected it was a consequence of the "declare before using" principle.  However this means that the wiki is incorrect.  It also follows that the program module cannot contain declarations of global variables.  Correct?
It's conceptually correct but, there is a way to declare variables in the program module and make them available in units used by the program, effectively and selectively turning them into global variables. 

The solution is found in the post of this thread https://forum.lazarus.freepascal.org/index.php/topic,45707.msg323530.html#msg323530

HTH.

Summary: using export/external.

I was wondering about those, but more in the context of dynamic linkage... which would of course be system-specific. Noting that this is effectively a language extension: is it reliable in all cases or are there some linkers etc. which will barf on it?

MarkMLl


MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 4015
Re: Trivial question about global vatiables
« Reply #10 on: February 24, 2021, 12:59:43 pm »
Summary: using export/external.

I was wondering about those, but more in the context of dynamic linkage... which would of course be system-specific. Noting that this is effectively a language extension: is it reliable in all cases or are there some linkers etc. which will barf on it?
At least in theory, the method is general.  Of course, it requires the language in use to support a mechanism to make variables declared in one module visible to other modules.  The most common mechanism is to declare the variable, possibly with a modifier such as "export" in the case of FPC, in one module and declare it as "external" in whatever other module wishes to use it.

The linkers are usually ready to deal with situations like that.  What could be a problem is the programming language not implementing a mechanism to provide the information to the linker.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018