Kenneth Pugh, a principal in Pugh-Killeen Associates teaches C language courses for corporations. He is the author of C Language for Programmers and All On C, and is a member on ANSI C Committee. He also does custom C programming for communications, graphics, and image databases. His address is 4201 University Dr., Suite 102, Durham, NC 27707.
You may fax questions for Ken to (919) 493-4390. When you hear the answering message, press the * button on your telephone. Ken also receives email at kpugh@dukeac.ac. duke. edu (Internet) or dukeac!kpugh (UUCP).
Q
Recently I had reason to write a short C program to convert a series of large BASIC files into another format.
Everything was fine except where the BASIC program had stored numbers as single or double precision floating point numbers. Microsoft C did not read in and convert these numbers correctly.
Am I correct in assuming that BASIC stores floating point numbers in a different format than C does? If so what is a routine which will do conversion between the formats?
Finnbarr P. Murphy Cork, Ireland
A
Perhaps a reader can tell us what internal representation BASIC uses for floating point numbers.
Your question raises an important issue for anyone who is trying to move data between environments whether the environmental differences be hardware, operating system, or (as in this case) development language.
The only sure path to data compatibility is to use ASCII characters for the numeric values (i. e. text format). (There is a possibility that the lowest order bit of floating point values may differ, but this is usually not a significant issue.)
You could write a BASIC program to dump the binary files in ASCII. A C program would then read the ASCII files and convert the data back to internal format. The data file is typically written in quote and command delimited format. For each record, the field values are printed out as:
value1, value2, value3 . . . (Newline)The Newline may be composed of either a single newline or a combination of carriage return/linefeed. If a comma appears in a value, then the value is enclosed in quotes. For example:
This is a field, "This is a comma, field", 333.45, 666.9 (Newline)This format is easy to generate in BASIC, but a little more difficult to parse in C. Because scanf stops reading string input at a white space, it is easier to read the entire string in with fgets() and then use the strpbrk() or strcspn() functions to break it into its parts.I know of only one binary floating point format that is guaranteed to be compatible among machines the IEEE standard. Most compilers do not support this relatively new standard, and the 80-bit long format is typically used only with compatible co-processors.
Q
I have a question about how the va_arg macros in Standard C include file <stdarg.h> are intended to be implemented and/or used. I have not seen this topic raised anywhere in the Standard C references I have, though I have not seen the actual text of the standard.
To pose the question, consider the following as a possible implementation intended for use in a 68000 environment:
typedef int * va_list; #define va_start (arg_ptr, first_param) \ (arg_ptr= (va_list) (&first_param+1)) #define va_arg(arg_ptr,type) \ (* (((type*) (arg_ptr= (va_list) ((type*) arg_ptr) +1))-1)) #define va_end(arg_ptr) (arg_ptr=NULL)The tortuous expression for va_arg is used because the typecasted pointer is not an 1value. (At least, that is what my compiler tells me if I try to use *((type*)arg_ptr)++).The problem appears when this definition is used with narrow types. For example, if a float value is passed, it will be widened to double when stored on the stack. The compiler is smart enough to recognize this fact for declared parameters, but the expression generated by the above va_arg macro would not.
The two solutions that I can see are: some kind of test for narrow types inside the macro; and restricting the use of va_arg to non-narrow types. The only way I can see to implement the first solution is to string-ize the type and generate code to test whether a narrow type is being used and handle it separately. This seems like a very undesirable solution. On the other hand, I have seen no mention of the restriction specified in the alternative. What am I missing?
Jeff Newmiller
Davis, CAA
I'm glad I don't come across those expressions too often in my programming. I haven't actually seen anyone use the variable argument macros in writing their own functions. They are useful for writing the standard printf and scanf family of functions in C, rather than in assembler.
The answer to your question lies in the standard. It reads "The va_arg macro expands to an expression that has the type and value of the next argument in the call..... if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined."
It would appear that solution #2 is your only choice.
If all types are integral multiples of the size of an integer, you can simplify your expression for va_arg by adding the sizeof(type) / sizeof(va_list) to arg_ptr. If not, then the expression will have to stay as it is.
Reader Requests
I have a customer in Florida using a VAX running VMS 5.0-2. I would like to write programs here in PA on MS-DOS and only transmit a finished product to the end user.To relieve the cost of telephone connect time, I would like to compile on my MS-DOS machine. I have heard of cross compilers from VMS to DOS. Have you heard of one that goes MS-DOS to VMS? Any answer would be appreciated.
Paul Hetherington
Levittown, PAQ
Is X-Windows available for the IBM-PC? Rumours claim that MIT freely distribute the C-source. It this true? And in case how may I obtain a copy?
Thanks for a splendid magazine, it is highly appreciated.
Sincerely,
Einar Valen
Ristangen
Haugland
5265 Y. Arna
NorwayA
I asked fellow CUJ columnist Sydney Weinstein to respond. Here is his answer.
The X Windowing system is split into two sections. The client that wants to display information and the server that displays the output the client generates. These two processes are connected by TCP-IP sockets. For IBM PCs there are several commercial X Server packages that reside on top of underlying TCP-IP networking packages. These packages are just ports of the MIT X distribution with changes necessary for the PC, and with varying amounts of optimization of the resulting server. Some of the commercial products run directly on the PC, some run on top of Microsoft Windows. Many vendors at UniForum 1990 in Washington, D.C. displayed MS-DOS X Servers. Of course, the commercial packages are just executable binaries.
If you wish to adapt your own X server from the sample X server and the sources provided from the X Consortium at MIT, order the X source tapes. These tapes include the complete code of the X system and many contributed programs, toolsets, and window managers. On January 4th, 1990, the MIT X Consortium announced Release 4 of the X Window System, Version 11. Quoting from their own release notice:
"The software in this release is not in the public domain, but is freely available without restrictions. No license is required and there are no royalties; vendors are actively encouraged to base products upon this software... a set of four 1600bpi tapes in UNIX tar format plus printed versions of the major manuals and a copy of the new Gettys, Newman, and Scheifler book X Window System: C Library and Protocol Reference are available from the MIT Software Center."
In North America, the manuals and books are priced at $125 (for tapes too, add $275). Abroad, the manuals and books go for $175 (for tapes, add $325). Prices include shipping.
To order, please send a letter and a check payable to MIT in US currency for the appropriate amount to:
MIT Software Distribution Center
Technology Licensing Office
Room E32-300
77 Massachusetts Avenue
Cambridge, MA 02139
Announcing The Great Name / Obscure Code Contest
As announced in the previous column, this contest has begun.Send examples of the worst names or abbreviations that you have seen in other people's programs (or even your own). Include both the name and a description of what it is supposed to represent. The best (or worst) examples will be published here, with credit for your submission. The name of the programmer who actually wrote the code in which the name is used will not be mentioned without his or her express permission.
For starters, here are some abbreviations that have appeared in various journals.
cls, dfthlp(), q_bsy(), revdot(), hpel, strlwr(), do_esq(), dld_charCan you determine the full name for the variable or function? These variables were found in programs from the following general application areas:
cls/* Window and File */ dfthlp() /* Windowing */ q_bsy()/* Queues */ revdot() /* Graphics */ hpel/* Graphics */ strlwr() /* General package */ do_esq() /* Communications */ dld_char /* Communications */ANSI C allows 32 characters for variable names; most linkers allow the same limit. What longer names would you choose?