Generating Code

You select the code generation model you want via the somewhat hidden dialog box shown in Figure 8-1. You get to this dialog box by clicking Options on the Make Project dialog box.

Figure 8-1 Visual Basic’s compiler options dialog boxes

As you can see in Figure 8-1, some extra compilation options and advanced optimization choices become available when you select Compile To Native Code. I’ll discuss some of these options a little later.

When you compile to native code, the Visual Basic 5 native code generator/compiler, C2.EXE, is run once for each code component in the project. For example, if a project has a form, Form1; a module, Module1; and a class, Class1; then C2.EXE is run once to compile each component. Each invocation’s options are the same depending on which you selected in the dialog box; that is, the options you select are used to compile the entire project. In case you’re interested, C2 runs as a multithreaded, Win32, 32-bit console process.

Each time the native code compiler is run, a hidden process (described as 16-bit by the Windows 95 Task Manager) is started and the code generator/compiler, also run as a hidden process, is run attached to this process. (In Windows 95, this process is run from the file WINOA386.MOD, with a process description of “Non-Windows application component for 386 enhanced mode.” This file is not required if you’re running under Windows NT.) As each invocation of C2 terminates, the instance of WINOLDAP (the module name given to WINOA386.MOD) in which it was run is also terminated. You should now start to see why this process might be slower than selecting p-code generation (which is an internal process and doesn’t use C2). Here’s what the command-line arguments of a typical run look like (with no optimizations):

C2 -il C:\WINDOWS\TEMP\VB819310 -f Form1 -W3 -Gy -G5 -Gs4096 -dos 
-Zl -FoC:\TEMP\Form1.OBJ -Qifdiv -ML -basic

These flags are explained in Table 8-1. Some of them are described in more detail here as well:

Table 8-1 Command-Line Flags for the C2 Compiler

Flag Explanation
-il C:\WINDOWS\TEMP\VB819310 Undocumented but also used for a C program; probably used to “name” intermediate language files
-f Form1 The input file to be compiled
-W3 Warning level 3
-Gy Enables function-level linking
-G5 Optimize for Pentium
-Gs4096 Turn off stack probes
-dos Undocumented but also used for a C program
-Zl Removes default library name from OBJ file
-FoC:\TEMP\Form1.OBJ Name of output file
-Qifdiv Performs Pentium FDIV erratum fix
-ML Creates a single-threaded executable file
-basic Undocumented but appears to be a new flag for Visual Basic compilation

Don’t bother to scan your Visual Basic 5 documentation for information about these flags because you won’t find any—they are all undocumented. If you have a set of documentation for the Visual C++ compiler, however, you might be in luck. Why? Because it seems that C2 is taken from the Visual C++ compiler. In fact, you’ll soon see why I’m pretty sure that C2.EXE is the C2 from Visual C++. Nevertheless, the above interpretation of the flag meanings is mine alone. Microsoft doesn’t document how its C++ compiler works beyond describing CL.EXE (the front end to the C compiler).

Visual Basic itself evidently provides the compiler’s first pass, unlike Visual C++ (in which in terms of compilers, CL.EXE is seemingly analogous to VB5.EXE), and the first pass (the parser and some of the optimizer) in C and C++ is apparently provided by C1.EXE (C) and C1XX.EXE (C++). C2.EXE appears to be in Visual Basic what it is in Visual C++—the code generator and optimizer (the part of it to do with generation).

How do I know? First, the way C2.EXE is driven is similar to the way the “real” C2.EXE, supplied with the Visual C++ compiler, is driven. Here’s the input to the C2 component of Visual C++ 5 (directive/invocation provided by CL.EXE) for a simple one-file C application named TEST.C:

MSC_CMD_FLAGS=-il C:\WINDOWS\TEMP\a54497 -f test.c -W 1 -G4 
-Gs4096 -dos -Fotest.obj -ML -Fdvc50.idb

I gathered this information using the same tool I used on Visual Basic 5’s C2. I’ll discuss the tool more fully a little later. For now, let’s forget the how and concentrate on the what.

Can you see the similarities? (For a more detailed explanation of these flags, see MSDN or Visual C++ itself.)

Second, I looked back on our prerelease Visual Basic 5 CDs and examined the evolution of this component, comparing what I found there with the C2.EXE file supplied with Microsoft’s Visual C++ 4.2 and 5 products. The results of my examination of the component’s version information are shown in Table 8-2.

As you can see from Table 8-2, the C2.EXE file in the Visual Basic alpha release had the same description as that of the real thing in Visual C++—this was later changed. (On the alpha and beta 1 CDs, the file C23.ERR was also supplied. This file [also supplied with Visual C++ 4.2], which contains error message text as used by the C compiler, has been removed from the packing list for the release version of Visual Basic 5 and for Visual C++ 5.)

Third, replacing the C2 of Visual C++ with that of Visual Basic 5 worked; that is, once I copied the file MSPDB41.DLL to the SharedIDE folder so that Visual

Table 8-2 The Evolution of the C2 Compiler

Application Compiler Version Number Compiler Description Compiler Product Name
Visual C++ 4.2 10.20 Microsoft 32-Bit C/C++ Compiler 80x86 Back End Microsoft Visual C++
Visual C++ 5 11.00 Microsoft 32-Bit C/C++ Compiler 80x86 Back End Microsoft 32-Bit C/C++ Optimizing Compiler
Visual Basic 5, last alpha 11.00 Microsoft 32-Bit C/C++ Compiler 80x86 Back End Microsoft 32-Bit C/C++ Optimizing Compiler
Visual Basic 5, betas, RC1*, and the marketing beta 11.00 Microsoft 32-Bit Visual Basic Compiler 80x86 Back End Microsoft 32-Bit Visual Basic Optimizing Compiler
Visual Basic 5, release 11.00 Microsoft 32-Bit Visual Basic Compiler 80x86 Back End Microsoft 32-Bit Visual Basic Optimizing Compiler

* RC1 stands for Release Candidate 1, the first version of the product that Microsoft believes is up to release standards. Depending on what comes back from the testers, this version might be the one that goes on sale.

C++ 5 could find it, a step that is not necessary if you compile from a DOS box rather than from the Visual C++ IDE, I could build C applications (such as the application shown in Listing 8-2 beginning on page 336) using Visual Basic’s C2.EXE with Visual C++ 5. (You can also use Visual Basic 5’s C2 with Visual C++ 4.2.) The reverse process also worked; I was able to compile and run a program in Visual Basic 5 using the C2 from Visual C++ 5. (This scenario does not work with Visual C++ 4.2, however, probably because of the -basic flag.)