From: wirzeniu@klaava.Helsinki.FI (Lars Wirzenius)
Newsgroups: comp.lang.c
Subject: Re: Problem in Turbo C/C++ with DOS.H
Date: 29 Sep 92 17:45:03 GMT
Organization: University of Helsinki

joec@fid.morgan.com (Joe Collins) wonders why a header file that is part
of his compiler's library gives compile errors like these:

>  VALUE OF TYPE VOID IS NOT ALLOWED
>  ) EXPECTED

and gives the following prototype as an example where it happens:

>unsigned _Cdecl _dos_write( int __fd,void far *__buf,unsigned __len,
>            unsigned __nread);

This looks like very strange C indeed.  Fortunately for this explanation
(if not my mental state), I have used DOS C compilers for some years,
and can hopefully parse it correctly.  [ For the "keep c.l.c pure from
environment specific questions" crowd, I hope to keep this close enough
to generic C. Flames to e-mail if I fail. ]

The first thing to notice, and get rid of, is the _Cdecl thingy.  It is
a macro that expands either to nothing, or to ``cdecl'', neither of
which are of interest for this particular problem.  Zap it, and we get
this (reformatted for hopefully more clarity):

    unsigned _dos_write(int __fd,
                        void far *__buf,
                        unsigned __len,
                        unsigned __nread);

Since the complaint was about type void not allowed, we turn our
inspecting eye to the second argument, since that is the only place
where the keyword void is used.  For somebody familiar with the MS-DOS
way of degenerating C, the keyword far looks quite familiar.  For others
more fortunate, you only need to know that it is a modifier for a
pointer type similar to unsigned being a modifier to int.  So the second
argument would seem to be a "far pointer to void", in other words, a
generic pointer with the far modifier.  It seems to be quite in order.
No problemo, as a certain movie character would express it.

In order not to sound like mathematicians during the 1920s (they
mathematically proved that bees can't fly, or something), I do have to
take note that something indeed is a problem.  By using my magical
powers, uh, by digging through my muddy memory, I seem to get the
feeling that you have invoked the compiler using a switch similar to the
"-A, use ANSI keywords only" switch, which makes the compiler not
recognize the far modifier.  In that case the error message would make
sense: the declaration would take "void" as the type and "far" as the
(here unnecessary) name for the parameter, which gives cause to the
first error message (parameters of type void are not allowed), and then
goes on to read the star, and get confused and complain a second time. 
Notice, by the way, that it is often not a good idea to get overly
fixated with the exact error messages after the first one, since
compilers have sometimes difficulties in getting past one error. 

I didn't like the above dense explanation either.  If I write the
troublesome parameter declaration using simpler and less obtrusive
names, like this:

	void foo * bar

then things will hopefully be clearer.  Take out foo, and the
declaration

	void * bar

is quite valid (it is a generic pointer, or something which can point at
any data, which is what is wanted by the prototype [trust me]).  With
foo around, it really doesn't make much sense.  The compiler reads first

	void foo

(not more, since the star doesn't make sense after a variable name),
which it interprets as an attempt to declare foo to have type void. 
Since this is not valid, it quite correctly complains.  

Satisfied for the moment, it continues to read the star, which it still
can't make any sense out of.  Because it thought that the declaration
for the parameter already ended, it was expecting either a comma and a
new declaration, or a right parenthesis to end the parameter list
altogether.  Being the clearspoken itself, it told you it was only
expecting the latter.  (Compilers are a bit stupid like that sometimes,
but that's why we love them so much.  :)

>WHAT IS WRONG? Should I speak to Borland about this or is there
>a compile option I need? 

Check if you have a "ANSI mode" switch on.  I don't think there is
anything really wrong with your C package, but in case you do talk with
them, try to get them to fix the header or headers so that they can be
compiled correctly with any sensible combination of switches.

I remember that I had similar problems with the very first version of
Borland's C compiler, way back in 1987.  Not that I cared very much
about that one, particularly since I was overjoyed when Borland sent me
a free upgrade when I reported a bug to them.  Of course, I have since
developed a strong tendency to avoid their compilers altoghether, but
that is mostly due to the Disk lOading System and for starting an affair
with Unix and gcc. 

--
Lars.Wirzenius@helsinki.fi, rambling, biased, and proud of it.
Newsgroups: comp.lang.c