Title: Why to recompile after changing global constant value? Post by: Anderson P. on July 05, 2017, 01:51:13 pm Hello
We have several constants declared inside a globals block, that is imported at other programs using the "globals" command. If we change the value of some constant in this external file, all the programs that import this constants present the error "The global 'gc_letras_com_acento' has been redefined with a different constant-value." and we have to recompile the programs to solve this. My question is, why don't Genero simply assumes this new constant value, instead of presenting the error? It has already loaded the constant value for doing the compare. We are trying to understand why it gives this error instead of assuming the new value. Thanks for your attention. Title: Re: Why to recompile after changing global constant value? Post by: Sebastien F. on July 05, 2017, 03:38:47 pm Hello Anderson,
In fact global files are "included" in the module where they are used, similarly to a preprocessor include <file>... I assume you doing something like this (using the Genero linker): Code
So yes, you have to recompile all the modules using your globals file, if this file was modified. You may want to define file dependencies with the tool you are using (make, GST?) For new developments, consider to review globals usage, an use IMPORT FGL with PUBLIC definitions in modules. This allows automatic chained compilation, see for ex: Code
Doc refs for IMPORT FGL: 3.00: http://4js.com/online_documentation/fjs-fgl-manual-html/#c_fgl_programs_IMPORT_FGL.html 3.10 EAP: https://4js.com/techdocs/fjs-fgl-manual/index.html#c_fgl_programs_IMPORT_FGL.html Title: Re: Why to recompile after changing global constant value? Post by: Anderson P. on July 05, 2017, 04:19:46 pm Sebastien, thanks for your reply.
We are aware that this "globals" approach is kind of depreciated, the problem is that all of our programs use a default global set of functions and variables, and seems like we can't have a "globals" and a "import fgl" at the same file, is one or other. Is that right? So we would have to replace the globals in all our programs with the import fgl, and to archive this will be necessary to change all the global set functions usage to include the module name. That's why we still use globals and can't use import fgl. I don't know if there is some workaround to use globals and import fgl at the same file. Title: Re: Why to recompile after changing global constant value? Post by: Sebastien F. on July 05, 2017, 05:29:50 pm Not sure to understand 100% what you mean by "global functions"...
Obviously all functions of a program are "global", we have no concept of "local" function (that you could define inside another function for example, in local scope). With Genero, functions can be PRIVATE or PUBLIC. Theoretically, you can mix GLOBAL and IMPORT FGL: Code
However, I can imagine that with real application code, it's not that simple to migrate to a new pattern. Furthermore, you can mix IMPORT FGL and fgllink linking. Please read carefully this page and get back to us, if you can't find the information you need: https://4js.com/techdocs/fjs-fgl-manual/index.html#c_fgl_programs_IMPORT_FGL.html Seb Title: Re: Why to recompile after changing global constant value? Post by: Anderson P. on July 05, 2017, 07:01:31 pm By global functions I meant functions that was defined inside a module imported using "globals", guess I expressed myself poorly.
And yes, indeed we can mix global and import fgl, but doing so we got a "warning" for every function that is inside the module imported using "globals". I remembered that we had some problems when we tested this, but don't remembered what was it, now i remembered that the problem was this warnings. But I have seen that the documentation you sent me talk about this -8406 warning, we will investigate this a bit more. Thanks for your attention. Title: Re: Why to recompile after changing global constant value? Post by: Sebastien F. on July 05, 2017, 07:59:22 pm Oh I think I start to understand what you do...
I guess you do following ( would be better that YOU provide the samples ;-) ): Code
Honestly, I have never seen functions declared in a globals file after the GLOBALS .. END GLOBALS block! I think this is supported by Genero to compile old legacy 4GL code, an undocumented c4gl feature... When the module is "included" with GLOBALS "glob.4gl", the compilers takes only global variables definitions. When the glob.4gl module is compiled, the global variables AND the functions are compiled, and then it can be linked as a regular module! Think of GLOBALS "file.4gl" as "include the GLOBALS ... END GLOBALS block from file.4gl". (You could in fact repeat the complete GLOBALS .. END GLOBALS block in each module, GLOBALS "file.4gl" is a shortcut) To late for me today to test with Informix c4gl, but after a quick look at the Informix 4gl books, I can see that this usage is not really legal: Quote Usage In general, a program variable is in scope only in the same FUNCTION, MAIN, or REPORT program block in which it was declared. To make its scope of reference the entire source module, you must specify a modular declaration, by locating the DEFINE statement outside of any program block. To extend the visibility of one or more module variables beyond the source module in which they are declared, you must take the following steps: 1. Declare variables in GLOBALS…END GLOBALS declarations (in files containing only GLOBALS, DEFINE, and DATABASE statements). 2. Specify the files in GLOBALS “filename” statements in each additional source module that includes statements referencing the variables. Here the Genero doc for GLOBALS: https://4js.com/techdocs/fjs-fgl-manual/index.html#c_fgl_Globals_003.html Summary: We can try to support undocumented c4gl features to allow you to compile old legacy code, but it gets hard for us to allow mixing such usage with new new Genero features... (sorry!) Seb Title: Re: Why to recompile after changing global constant value? Post by: Anderson P. on July 05, 2017, 08:58:55 pm Sebastien, I understand, and indeed this module is a very old code that we use in all our programs to perform the user login.
We have always used it, and will take a considerable work do change it, but I guess it has to be done. I think that the behavior is correct, when I created the topic it was not clear for me that the globals work just like the include, but now I understand. Thanks for all your attention, now it's up to us to convert this globals to fgl import. Title: Re: Why to recompile after changing global constant value? Post by: Sebastien F. on July 05, 2017, 09:12:12 pm No prob Anderson, our goal is to help you.
Just tested with Informix c4gl.... This test confirms that it is a behavior from I4GL (at least in C-compiled mode): Code
Seb Title: Re: Why to recompile after changing global constant value? Post by: Sebastien F. on July 05, 2017, 09:21:58 pm Oh... In fact it is documented Genero feature !!!
https://4js.com/techdocs/fjs-fgl-manual/index.html#c_fgl_Globals_006.html Seb Title: Re: Why to recompile after changing global constant value? Post by: Reuben B. on July 06, 2017, 12:42:51 am Sebastien, thanks for your reply. We are aware that this "globals" approach is kind of depreciated, the problem is that all of our programs use a default global set of functions and variables, and seems like we can't have a "globals" and a "import fgl" at the same file, is one or other. Is that right? So we would have to replace the globals in all our programs with the import fgl, and to archive this will be necessary to change all the global set functions usage to include the module name. That's why we still use globals and can't use import fgl. I don't know if there is some workaround to use globals and import fgl at the same file. with regard to your comment "and to archive (I think you meant achieve) this will be necessary to change all the global set functions usage to include the module name" if the function name / variable name was unique, you would not have to "change all the global set functions usage to include the module name" Code
>fglcomp foo.4gl >fglcomp main.4gl >fglrun main.42m bar 0 0 Whilst it would be preferable and I'd argue a good standard to adhere to prefix with the module name e.g. in the above code I would rather see DISPLAY foo.bar() LET foo.x = 0 DISPLAY foo.ZERO etc, it isn't necessary if the imported function/variable/constant name is unique. With "gc_letras_com_acento" I'm guessing gc stands for global constant, so it should be unique enough that your code change is GLOBALS "globals_file" TO IMPORT FGL globals_file, and changing CONSTANT gc_letras_com_acento ... to PUBLIC CONSTANT gc_letras_com_acento ..., and you should not have to change all references of gc_letras_com_acento to globals_file.gc_letras_com_acento, if that is what you are afraid of. Also with your original question ... Code ... to help understand, do something like od -c program-name.42r or strings program-name.42r, and fglrun -r module-name.42m (you might need to create a small example to make it all easier to read and interpret). A common misconception is that a .42r is like a binary executable, it is not. All the computational logic is inside each .42m. The fglrun -r shows some of this logic, you'll see it pushing constants onto a stack, pointers to the constant values etc Number of constants: 1 0 INTEGER `100' Global variables: HUNDRED 0 INTEGER ... pushGlb HUNDRED This is repeated in each of the .42m. So if the runner detects where the global constant in one .42m is different than the value of the same global constant in another .42m, then the decision is made to stop rather than assuming one value is more correct than the other. Hope that helps Reuben |