Relearning MSX #14: MSX-C commands: FPC.COM
Posted by Javi Lavandeira in How-to, MSX, Retro, Technology | February 16, 2015This is the second post describing MSX-C’s command line tools. In the previous article we examined the parser (CF.COM), and today we’ll see the Function Parameter Checker (FPC.COM).
As before, this post is rather technical and assumes experience programming in C. It’s targetted at users who already have experience programming in C. However, I still recommend to read it at least once if you’re a beginner, because it will familiarize you with problems you’ll find in the future.
FPC.COM : Function Parameter Checker
First of all, using FPC is optional. Its job is to reduce the number of software bugs by checking that the values returned by functions and the parameters passed to them are of the right type. If you’re confident that your code is correct then you can completely skip it, but I recommend you to use it.
FPC has two modes of operation:
- Check the program for errors
- Create a skeleton .TCO file containing only the information FPC needs to do its job
The first mode of operation uses the command line options -s, -u, -t and -i. The second mode uses -c and optionally -d.
Mode 1: check the program for errors
FPC runs in this mode when we don’t use the -c option. The command line syntax is as follows:
FPC [-i] [-s] [-t] [-u] file1 file2 ...
The parameters file1, file2, etc, are the file names of intermediate code files (.TCO) that FPC needs to search for function definitions. For example, if our code uses the standard library then we need to tell FPC to check the LIB.TCO file. The file extension is optional and defaults to .TCO.
Let’s start with a basic example. Consider the 1.c program taken from page 32 of the MSX-C user’s manual:
In the first line of main() this program declares two functions f1() and f2(), both returning integer values. The definitions are after the main() function:
- f1() returns an integer, and takes two integer parameters
- f2() returns a char (instead of an integer as per the earlier declaration) and takes no parameters
Leaving aside the mismatch in the f2() function definition, there are a couple of problems with this code:
x = f1('a', 3);
This line calls f1() with two parameters, the first of which is a char, even though f1() takes two ints.
y = f2();
The variable y is of type int, but the f2() function returns a char. CF will happily process this program because the code is syntactically correct:
These two bugs will cause the program to misbehave and maybe even hang the computer. This is why FPC is useful: it will check the parameters of each function one by one and tell us what we did wrong:
In the example above FPC checks the function definitions in the files LIB.TCO and 1.TCO
The command line options in this mode are:
-s
Continue processing the batch file even if there are any processing errors. This option behaves in the same way as the -s option in CF.COM.
-u
Makes FPC not to return an error when it can’t find a function in any of the .TCO files specified in the command line. Consider the previous example, but omitting the LIB.TCO file from the command line:
In this example FPC checks only the file 1.TCO, and it returns an error message when it can’t find the printf() function there. The -u switch makes it ignore the functions it can’t find:
-t
Causes FPC to perform more strict type checking. By default it treats the types int, unsigned and pointers as equivalent. Adding this option to the command line makes FPC consider them different types.
-i
By default FPC skips indirect function calls in C code because it can’t check whether the parameters are correct, since the function that will be called won’t be known until runtime. This command line option makes FPC issue a warning whenever it sees an indirect function call, notifying us that this call can’t be checked.
Let’s illustrate this with an example. Take a look at the following program:
This program defines two pointers to functions (func1 and func2). func1 points to the times2() function, and func2 points to the strchr() function defined in string.h.
Without the -i command line option FPC won’t complain when checking this file:
The -i option causes FPC to issue a warning whenever it encounters an indirect function call:
Mode 2: Create a skeleton .TCO file
When FPC sees the -c option it will ignore the -s, -u, -t and -i options, and it will operate in a different way. Instead of searching for parameter errors, it will generate a single summarized .TCO file containing the function names and parameter types. This is all the information FPC needs to do its job.
This is useful when we’re building our own code library. If we have a lots of functions then the .TCO file will be big. It will take more space and FPC will take longer to process it. This option creates a smaller .TCO that can’t be processed by CG to create an assembler file (we will see this in the next post), but can still be used by FPC to check for errors in the program.
Let’s see an example. First we run CF on the 1.c file that we saw at the beginning of this post. This creates a file called 1.TCO that is 300 bytes long:
We can see the contents of this file using the TYPE command:
TYPE 1.C
The output is a lot of intermediate code that we can’t make sense of, but this somehow makes sense CG.COM:
This file includes all the function headers and also the intermediate code needed to generate the assembler code. In this case it’s just a very simple program, so the file is small. However, if this file contained lots of functions then it would contain lots of code that FPC doesn’t need. The -c option creates a file with just the function headers.
If we use the example above, the new .TCO file is only 68 bytes long and contains just the function headers:
FPC can also consolidate several TCO files into a single summarized file:
The example above consolidates the files LIB.TCO and 1.TCO into a single SUMM.TCO file that contains the headers for all the functions defined in them.
You may remember that we copied some TCO files to A:\UTILS when we installed MSX-C and MSX-C Library. These files are also compressed (as the MSX-C User’s Manual calls them), and contain only the headers of the library functions.
Now we know how FPC works in this mode. Let’s see the two command line options:
-c <output filename>
Create a compressed TCO file. The filename extension will default to .TCO if ommited. This option supports specifying a drive letter and path.
-d <function,function,function,…>
Some functions have a varaible number of parameters, or parameters of different types depending on how they’re called. The bdos() and bdosh() functions are nice examples. Because of this, FPC can’t check whether the parameters passed to them are correct. With the -d option we can specify a list of functions that FPC will ignore when checking for errors using the compressed TCO file created with -c:
In the example above FPC will create a SUMM.TCO file containing the headers of all the functions defined in LIB.TCO, MSXBIOS.TCO and 1.TCO. When using the SUMM.TCO file to check for errors it will ignore the functions bdos() and bdosh().
In the next post…
We will see the last of the MSX-C command line tools, the code generator (CG.COM).
This series of articles is supported by your donations. If you’re willing and able to donate, please visit the link below to register a small pledge. Every little amount helps.
Javi Lavandeira’s Patreon page
Pingback: Relearning MSX #14: MSX-C commands: FPC.COM | Vintage is the New Old