Synergex Celebrates 40th Anniversary
April 15, 2016One IDE to Rule Them All
May 18, 2016Transitioning to simpler, more manageable prototyping in Synergy/DE 10.3.3
We’ve made major changes to the Synergy Prototype utility (dblproto) and the compiler in 10.3.3 (scheduled for release next week). These changes correct problems that made it impossible to prototype some classes without CRC errors, as well as problems with missing and erroneous prototypes. They also improve performance, significantly reducing the overhead required to generate and use prototypes. But the first thing you’ll notice is how much simpler prototyping is now. Remember the hundreds of prototype files you used to generate? And the lengthy and complicated filenames? All gone—now when you run dblproto on a directory full of files, it will create a single .dbp file that contains prototypes for multiple files, and you can name that file anything you like (as long as it has a .dbp extension). The only bump on the road to attaining prototype simplification is that you’ll have to regenerate prototypes and maybe make some code changes. The changes to dblproto had a follow-on effect, so there are also changes to importing and SYNDEFNS and some other things. These changes may break your code and highlight coding errors. This article will try to help you make sense of the changes and ease the transition to 10.3.3.
First, a quick review. There are two reasons to use prototyping: to make declarations within a namespace available to other Synergy source files via the IMPORT statement; and to strongly prototype traditional Synergy code, which ensures that calls match their routine definitions. Even if you don’t need to import namespaces, implementing strong prototype validation can improve your code and your processes, because it enables you to detect more problems at compile time, rather than waiting until runtime.
When you regenerate prototypes, use the -out option to specify a filename. We recommend you use wildcards to prototype all the .dbl files in a directory into a single prototype file. If you previously used the -single option, don’t—it’s been deprecated because there’s no need for it now. If you used -single to improve performance on a 32-bit machine, you can now use the 64-bit version of dblproto (on a 64-bit machine, of course) with the new -platform=x86 option, which will target 32-bit.
Once you’ve generated your prototype file, put it somewhere the compiler can find it, and set SYNIMPDIR to that directory. When you compile, if there‘s a .dbp file in the SYNIMPDIR directory, the compiler will automatically perform strong prototype validation. Previously, you needed an IMPORT statement in your code to request prototype validation. Now, the only time you need an IMPORT statement is when you actually want to import something.
And that’s a perfect segue into our next topic: changes to importing. As stated above, the role of the IMPORT statement has changed. Now it is used only to import a namespace, which enables you to use members of that namespace without having to type the fully qualified member name. For example, if you have a namespace MyNamespace, which contains MyClass and MyMethod, you can use MyMethod like this:
MyNamespace.MyClass.MyMethod()
But if you import MyNamespace, you can do this:
import MyNamespace
...
MyClass.MyMethod()
The scope of an IMPORT statement is limited to the file in which it is imported. Previously, this was not the case in traditional Synergy, where a namespace that was defined outside the compilation unit and then imported with the IMPORT statement was available to all subsequent source files on the dbl command line. This behavior was neither intentional nor desirable, but rather an artifact of the way the compiler handled multiple files on a command line. If your code took advantage of it, you’ll get compiler errors now (NFND, NVTF, NVTP, or NVTPR), and you’ll need to add IMPORT statements to files that previously compiled without them.
There’s another reason you might need to add IMPORT statements. Previously, any namespace defined in a compilation unit was available to all the source files in that compilation unit. Now, a namespace defined in a file is available only to that file. If you want to use it in another file, you need to import it with an IMPORT statement or with SYNDEFNS. If you have this problem in your code, you’ll see those same compiler errors mentioned above. If you don’t want to add IMPORT statements, you can add the namespaces to SYNDEFNS, which has been expanded to take multiple namespaces. The first one listed is considered the default (routines without a namespace will be put in this namespace when prototypes are generated), and all of the namespaces listed will be imported.
There’s one more change to IMPORT: the directory argument has been deprecated and will be ignored. (The compiler will generate a warning, IMPDIRIGN, if it encounters a lingering directory argument.) Instead, specify the location of prototype files with the SYNIMPDIR environment variable or on the compiler command line with the -qimpdir option.
This sounds like a lot to do, but it breaks down into just a few steps:
- Delete your old prototype files and generate new ones, specifying a filename with -out.
- Set SYNIMPDIR to point to the location of the prototypes.
- Compile and see if you get errors such as NFND, NVTF, NVTP, or NVTPR, or the warning IMPDIRIGN.
- Track down where the missing IMPORT statements need to go. Either add IMPORT statements for all the namespaces that need them or redefine SYNDEFNS to include the namespaces.
- If you get an IMPDIRIGN warning, remove the directory argument from existing IMPORT statements.
- Rejoice in the simplification.
For details on all these changes, see the 10.3.3 DBL release notes (rel_dbl.txt), and then check the Quick Migration Guide (PDF) for more information on the changes you need to make to your code. (Even if you are upgrading to 10.3.3 from 10.1 or 10.3.1, see the Synergy DBL required changes table in the “Migrating from Version 9 to Version 10.3.3” section of the QMG. The dblproto and importing changes in this section apply to upgrades from both v9 and v10.)