VFP Public Variables

Posted on 2012-09-14
Last Modified: 2012-09-16
Hi all. This program I am working in assigns nearly 60 public variables during startup. They are not released until the program closes.

I was wondering if this is normal/typical, and if there could be any problems associated with this many variables being held in memory.
Question by:formadmirer
    LVL 3

    Assisted Solution

    This is common in Foxpro applications although not recommended.  There should be no issues with memory or anything like that.
    LVL 29

    Assisted Solution

    by:Olaf Doschke
    If a framework is used, the only common public variable is goApp, the instance of an application object.

    No, this is not common, you don't need public variables in VFP.

    There are all the issues with public variables, for which you also avoid them in other languages.

    And there is one buggy unwanted behaviour:
    If you pass a PUBLIC variable to a procedure OR a function by reference, then the PUBLIC variable becomes hidden (see example code below).
    (quoted from

    It's an ill usage of a public variable to pass it on as a parameter, but it happens, if a developer comes in late and doesn't know this is a public var.

    There are some public variables you can't avoid: System variables. The mostly are settings which partly could also be environment variables as set with the SET command. For the one or other reason there are settings and sysvars, VFP is a historically grown language with a big emphasis on downward compatibility in favor of cleanness.

    Bye, Olaf.
    LVL 41

    Assisted Solution

    I don't see any cons against public variables set at one place in program init. The memory consumed is marginal because you can have hundreds of variables and thousands of properties.

    The problem could be public variables created and changed at various places in the code. Such variables are hard to maintain.

    Od course, the issue described at Fox wikis exists from the beginning and experienced developers know about it. Same rule applies for PRIVATE variables as well. And less experienced developers are able to learn this feature easily... If you name public variables properly (e.g. giving them Gx prefix - x describes the data type here) then you can avoid public variables incorrect usage.

    New trends in OO programing were trying to suppress public variables but the code base already written in older FoxPro versions and still working under VFP is the main reason why public variables are still used.

    If your program works correctly then no reason to change it exists.

    Author Comment

    I was not previously aware of the issue regarding a public variable 'disappearing' when passed to a Procedure or Function.

    AFAIK we've never had any issues with the use of these public variables in our program, and they are all preceded with a lower case 'p' to safeguard their use throughout the program.

    I just wasn't sure what kind of memory each of these variables was likely to consume, and didn't know if that was something to be concerned about or not.

    They are mostly used to store path and file locations, and I added a few like one that holds my MySQL connect string.
    LVL 12

    Accepted Solution

    Public variables can be passed to a Procedure or Function where they are received as PARAMETERS which most often are local to that piece of code

    Or they can be used as-is (not passed) within those pieces of code.

    The use of PUBLIC variables was once very common, so if your code is older, it is not un-expected.

    However more current programming approaches discourage the use of PUBLIC variables.

    Regardless, they should work for you if you want to use them.

    If you have questions regarding if their use in a PROCEDURE or FUNCTION is modifying their content (or not modifying it), just put in code to debug your development (Breakpoints and/or SET STEP ON commands) and test the results.

    Good Luck
    LVL 29

    Expert Comment

    by:Olaf Doschke
    Usage of public vars is no go for me. tT seems I'm the only hardliner here. What I agree is, that the memory usage and the amount of them is not a problem. VFP allows infiinite array elements, the memory is your limit, nothing else (in previous versions there was a limit of 65000 elements per array). From that perspective 60 public vars are a small number.

    Just take some third party module from a developer having had the same idea about a name of a poblic var and you have a problem. That's the hardest problem of public vars. Another side of them is, you have to know their names, Have = value and create this goApp during development time and you can find your config properties via Intellisense. Even just that would speak against such public vars and in favor of a goApp object you extend with subobjects.

    Also you don't need a connection string public, you just will have one central class connecting to the server, and only that needs to know the connection string. So in this sense the need of public vars show a lack of centralising code.

    In regard of config, create a DBF or INF or XML file with simple name/value pairs, configpropertyname, eg data dir and configvalue, eg path to data. Read that into an EMPTY object.

    Use config (config dbf has fields property and value)
       Addproperty(goApp.Config,, config.value)

    Open in new window

    That's that  in very short, you can add code checking for double properties, invalid property names, you can also use a primary index to avoid double names.

    It's all about better organising yourself and better describing the scope of things.

    All I really need in any place is an identifier for the currently logged in user and the currently selected lanmguage, if my app is localised. I may need some paths, but that is having a smaller scope, eg only reporting modules need to know location of frx files, if I leave them external for dynamically changing them at runtime. But the whole application doesn't need top know their path.

    And from that perspective 60 is a huge number, you can have the same overview about your config values in a config.dbf and then add some more fields to denote a type and usage or whatever to organise yourself better.

    Bye, Olaf.
    LVL 29

    Expert Comment

    by:Olaf Doschke
    One more thing you can do to avoid a name overlap, even in such a common name as goApp.Config is, just create a subobject goApp.MyApp or goApp.MyCompany, and add everything else at that level. There is no need to avoid a name conflict of goApp, as you will not really be able to make use of two frameworks at the same time. Even if there would only be the need to merge their application class. Therefor it's also good as a framework developer to keet that application class itself very lightweight and let modules dock to it.

    Bye, Olaf.
    LVL 27

    Assisted Solution

    FoxPro evolved over the years and yes there are many coding techniques.

    In the beginning memory variables were name m.variable.
    Later there were types and visibility and types.

    nNumber, cString: n = Numeric and c = Character
    lnNumber, gcString (l = Local and g = Global).

    Open in new window

    You can also do without public variables.

    Once someone mentioned using over 1000 public variables. FoxPro will still run fast since today computers are extremely fast and have much larger memory compared to two decades ago.

    I personally would advise to restrict the use of Public Variables to the minimum: Ex. UserID, Settings Ini File in case you have many like I do (Customizations).
    LVL 41

    Expert Comment

    Olaf, if you are so strict in public variables usage then you should not use even the goApp :-)

    goApp is just "hardcoded" reference to the "application pyramid top" which is not good practice. Each application should have its own reference named ThisApplication and this object should be visible just in the application thread...

    So you should not use goApp as a public variable but you should create private variable in a main program/form and name it ThisApplication. This will ensure compatibility even in multithreaded environment when it will be implemented to VFP language. :-)

    OK, more seriously now: To refactor debugged and working code designed in FoxPro 1/2.x is waste of the time. And almost everybody has such code in a drawer... You can

    To avoid problem with hidden public variable (which is also valid for private variables) you may simply enclose the variable name in parenthesis when calling a function or procedure:

    llResult = MyBadFunction( (m.gcGlobalPath), m.AnotherParam)
    LVL 29

    Expert Comment

    by:Olaf Doschke
    Application pyramid top, Well, that's how it is, I don't see any difference if declaring aprivate var in main or a public var somwhere in a factory or  whatever is taken to create object. I can live with this one hardcoded reference, as I can make use of goApp.MyApp.translate() or goApp.MyApp.userid or goApp.MyApp.nMySQLHandle. I don`t follow you, how a private variable would be visible in multiple threads and public vars not.

    You can also argue this is really not just reducing the number of public things, it's just using properties instead of variables. But it's all about the namespace(s) and the hierarchy you build with it.

    If it ain't broke, don't touch it. I mainly agree, but you can put some effort in it, you don't need to do it in one go, and it will help if you use third party code to incorporate this into the "application pyramid".

    Bye, Olaf.

    Author Closing Comment

    Evidently this is a hot topic and one that often leads to somewhat heated debates, as I saw on the fox. page.

    All I needed to know is if the code I am working on is OK in it's current state with using 60 public variables during the startup process.

    I now know that maybe this isn't ideal coding practice by today's standards, but also that it is not unheard of and that actually 60 public vars isn't all that many, and won't have a negative impact on system memory available.

    Thanks to everyone for their input!
    LVL 29

    Expert Comment

    by:Olaf Doschke
    > 60 public vars ... won't have a negative impact on system memory available.
    How do you get that idea, at all?

    Public variables don't take more memory than local, they just have a global scope, they don't release.

    The impact on memory is of course depending on what is put into them. But a path is just a few bytes, magnitude 100 perhaps. If that's the mean memory usage we talk of 6KB. Public vars don't effect memory or performance.

    And the main question can also be answered: If it works, then it works. And it's not probable the 60 public vars were introduced just in the last few days. I assume the app ran quite some time and so that already answers that anything you find can work. But that's not answering the question if it's good practice, if it's usable, maintainable, understandable, extensible. There are many aspects of code that should be pushed to an overall better quality.

    In larger and longer running projects you can often see the effect code quality degrades over time, an application wears out, get's less extensible, has too many dependencies and side effects of changes and is less good to refactor.

    You can detect errors in variable scope definitions quite easy. If some value get's passed to very many methods of a class, then it's a sign that parameter should rather be a property of the class, püerhaps. As public vars don't need to be passed on this bad design will not be revealed. lists some more interesting characterisitcs of public vars and their redifinition: If you create a public var in main.prg and redefine it somewhere via PUBLIC you don't get an error. Sounds nice, but a redefinition of it indicates that programmer doesn't know it's a public var already and most probably has another usage of it. Surely it will not only be redeclared, but also set to another value, and that then breaks code at other places depending on the initial value. Those are hard to understand and debug errors. You'll first look into main and see the value assigned is correct and then scratch your head, until you finally will perhaps use Code References to see where else this variable is set.

    And defining variables as private in main doesn't change that.

    The answer in my oppinion is to change from public informations as you have in public variables to available application modules not only holding the information but also being able to work with them. Your oop design can reflect the real world, implementing colleagues having a certain job and knowing all the needed rules. And you rather delegate tasks to them then just ask them for the infos needed to do something at the caller level.

    That thought keeps you from reimplementing the same code more than once and that makes use of the most important pattern of modern development: loose coupling. Keep close together what belongs close together and loosely couple these objects to work with related objects. Rather program in a way "do this form me", than "give me the information I need to do it my way".

    A database manager class for example will connect to the database and all any other component may need is the succcess of connection or an error level, if there is, and the connection handle.

    Keep these jobs or roles small, eg a database manager should manage database connections only, perhaps, and leave data access to dataaccess classes, which can all inherit from a base class and all make use of the database manager, so the database manager can also log and do statistics on how many components request a connection and if it's perhaps a good idea to make more connections and load balance or jsut use one connection, to keep it opened or close it at times of very low usage. This is not the job of the single dataaccess objects anymore. And a public variable may hold the connection handle, but can't do that kind of logic, it's just a dumb variable.

    Bye, Olaf.

    Featured Post

    Find Ransomware Secrets With All-Source Analysis

    Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

    Join & Write a Comment

    Microsoft Visual FoxPro (short VFP) is a programming language with it’s own IDE and database, ranking somewhat between Access and VB.NET + SQL Server (Express). Product Description: (http://msd…
    Great sound, comfort and fit, excellent build quality, versatility, compatibility. These are just some of the many reasons for choosing a headset from Sennheiser.
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

    729 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now