Determine the size of malloc

J

James Harris

....
On the other hand, if lcc-win had provided fggets and ggets by
declaring them in their own separate header, "ggets.h", then I could
invoke lcc-win in conforming mode *and* use fggets and ggets, simply
by adding ``#include <ggets.h>'', or perhaps ``#include "ggets.h"''.

My point exactly. If this is doable that answers my question.
I really don't see how shoving non-standard content into a standard
header is of any help to anyone (beyond perhaps saving a few
keystrokes).

Ditto.
 
H

Harald van Dijk

[Context:
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__ /* TC2 is peculiar */
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));

} /* akeyboard */ ]

No you can't. gcc -ansi -pedantic adheres to the C standard.

Yes you can. When reserved identifiers are defined, the C standard allows
<stdio.h> to declare fileno and isatty, as the behaviour is undefined.
POSIX specifies a particular reserved identifier to define, and what value
to give it. Implementations in practise either do not provide the
functions at all, or support this identifier.
 
K

Keith Thompson

CBFalconer said:
No you can't. gcc -ansi -pedantic adheres to the C standard. The
items mentioned in the code (something like fileno and isatty) will
not appear in stdio.h. unistd.h is not a standard C header file at
all. The arrangements I made handle both gcc and Turbo C (useful
for checking 16 bit compliance).

"gcc -ansi -pedantic" does not forbid the use of non-standard headers,
nor should it do so. <unistd.h> is not defined by the C standard. It
provides a set of extensions in the form of additional declarations.
This is, in my opinion, the ideal way to provide an extension. The
use of the header is sufficient to indicate that the program is using
something outside the C standard.

The fact that POSIX adds declarations to <stdio.h> is a bit
problematic. The workaround, if I recall correctly, is that these
declarations are enabled only if a certain preprocessor symbol is
defined (I don't remember the details).

It would be better, IMHO, if POSIX left the C standard headers alone
(other than some additional requirements such as CHAR_BIT==8) and put
all its own declarations into its own headers.

But, to be fair to POSIX, I think that the existence of fileno() in
<stdio.h> predates the original ANSI C standard. ANSI's choice to
standardize the functions that work on FILE*, and not the ones that
work on int file descriptors, was, IMHO, a good one, but it was ANSI,
not POSIX, that broke with existing practice.
 
K

Keith Thompson

Richard Heathfield said:
James Harris said: [...]
This seems to me (yes, my opinion if you like) on
its own to directly outweigh the 'disadvantage' of the extra typing.
However, that's a side point. The main query is whether a community-
provided function can be distributed such that the above #include
would be valid whether telling the compiler to use ansi compatibility
or not.

An implementation is permitted to provide extensions provided they don't
break any strictly conforming program - that is, those extensions (the
ones that don't break strictly conforming programs) can be provided even
in conforming mode.

Right. To expand on that:

Suppose, for example, that a hypothetical compiler called xyzcc
provides ggets and fggets. (We will ignore any possible problems with
those functions (well, a macro and a function, but we'll ignore that
too).) It happens that ggets and fggets are implemented in portable
C, but that's beside the point.

Suppose that xyzcc provides the declarations of ggets and fggets in a
separate implementation-defined header, <ggets.h>. Then consider the
following program:

#include <stdlib.h>
#include <stdio.h>
#include <ggets.h>
int main(void)
{
char *line;
ggets(&line);
puts(line);
free(line);
return 0;
}

Strictly speaking, ``#include <ggets.h>'' causes the program to
exhibit undefined behavior (by omission, since the standard does not
define the behavior of any program with ``#include <ggets.h>''). For
all we know *based only on the standard*, <ggets.h> could contain code
that makes demons fly out of your nose. But the include directive is
neither a syntax error nor a constraint violation, so no diagnostic is
required. (Another implementation might reject the translation unit
with a diagnostic, perhaps because <ggets.h> doesn't exist.)

Similarly, the behavior of the statement ``ggets(&line);'' is not
defined by the standard. More precisely, the standard says that it
calls a function named ``ggets'' with the address of ``line'' as the
single argument, but it doesn't say how the function ``ggets'' itself
behaves. But again, there is no syntax error or constraint violation,
so no diagnostic is required.

An implementation *could*, in some super-strict mode, issue a
diagnostic warning that the use of <ggets.h> is non-portable, but this
is not required or even encouraged by the standard. As a practical
matter, anyone who's sufficiently familiar with the language will
already know that <ggets.h> is non-standard. (On the other hand,
someone who's not sufficiently familiar with the language might not
know this -- and someone trying to assess the portability of a large
body of code may not be able to find such non-portable constructs very
easily.) A compiler that accepts only truly portable C code, or at
least warns about anything that's not truly portable, would be a nice
thing to have, but the standard doesn't require it.

So the implementation is allowed to compile the above translation unit
without issuing any diagnostics. Furthermore, it's free to define the
behavior of any construct that's not defined by the standard itself.
On top of that, since no strictly conforming program can use
<ggets.h>, this extension cannot affect the behavior of any strictly
conforming program.
 
A

Antoninus Twink

A compiler that accepts only truly portable C code, or at least warns
about anything that's not truly portable, would be a nice thing to
have, but the standard doesn't require it.

It would be a completely pointless thing to have, unless your horizons
are limited to solving the exercises in K&R. Oh, excluding Chapter 8, of
course...
 
K

Keith Thompson

CBFalconer said:
Keith Thompson wrote:
... snip ...

It can't.

Huh? What can't what?
fileno goes with the read, open, close etc. functions
which don't appear in standard C.

Yes, but fileno() also goes with the standard C functions that
use FILE*. The declaration is:

int fileno(FILE *stream);

At the very least, such a function would depend on <stdio.h>. And, in
fact, POSIX requires fileno() to be declared in <stdio.h>. It
specifies the _POSIX_C_SOURCE macro (or, in an earlier POSIX standard,
_POSIX_SOURCE) as the way to enable it.
This doesn't prevent having an
integer, but does prevent using 'isatty' etc.

Sorry, you're going to have to explain that. What doesn't prevent who
or what from having what integer?

To stay within the bounds of topicality:

Adding declarations to C standard headers, but making them visible
only when a macro in the implementation name space is defined, is an
acceptable way to provide extensions. Adding those declarations to a
non-standard header is, in my opinion, a better way to do this.
(POSIX, as I understand it, was forced to use the former method
because of historical practice that pre-dates both the C standard and
the POSIX standard.)
 
R

Richard Bos

CBFalconer said:
No you can't. gcc -ansi -pedantic adheres to the C standard.

And the code doesn't. It uses functions from POSIX. No problems with
POSIX - provided you don't try to pass it off as ISO C. Which this code
does. IMO, that's lying.

Richard
 
K

Keith Thompson

CBFalconer said:
And you didn't bother to read the code, which has been snipped. If
you did you would see that it takes care to declare those external
functions used, which operation has nothing to do with POSIX. It
is non-standard in that the linked libaries must contain the
appropriate routines.

The existence of those particular routines has everything to do with
POSIX.

Manually writing your own declaration for a function, rather than
#include'ing the standard header (in this case, POSIX standard, not C
standard) that declares it, is absurd.

[...]
 
K

Keith Thompson

CBFalconer said:
No it isn't, because I know what that portion will do, at least on
my machines. I want to compile the rest of the program with the
full gcc protection. That routine was liberally marked as
non-portable.

So isolate it in its own source file and treat it as non-portable,
using a different set of options to compile it.

I repeat, manually writing your own declaration for a function
.... (see above). Headers exist for very good reasons.
 
R

Richard Bos

CBFalconer said:
And you didn't bother to read the code, which has been snipped.

Actually, I did.
If you did you would see that it takes care to declare those external
functions used, which operation has nothing to do with POSIX.

Actually, it does. Those functions _are_ POSIX, and your private
declarations are hiding that. Don't Do That.

Richard
 
N

Nick Keighley

static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__ /* TC2 is peculiar */
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));

} /* akeyboard */ ]

Richard Bos wrote:
No you can't. gcc -ansi -pedantic adheres to the C standard.

Yes you can. When reserved identifiers are defined, the C standard allows
<stdio.h> to declare fileno and isatty, as the behaviour is undefined.
POSIX specifies a particular reserved identifier to define, and what value
to give it. Implementations in practise either do not provide the
functions at all, or support this identifier.

If the OP wants to write Posix code why not put the correct headers in
and omit -ansi -pedantic (after all it *isn't* ANSI-C)
and *** don't redefine the Posix stuff ***. I'm in the middle
of porting code from one unix to another and I'm mostly removing
incompatible definitions from the application's C files. Use
the right headers!
 
H

Harald van Dijk

If the OP wants to write Posix code why not put the correct headers in
and omit -ansi -pedantic (after all it *isn't* ANSI-C)

-ansi -pedantic don't mean you're writing a conforming (I mean "correct")
program, they mean you want your code to be compiled by a conforming
compiler. POSIX doesn't define any behaviour of C compilers that fail to
conform to the C standard. If you want to write POSIX code, and you want
to use gcc, you should use the -ansi -pedantic options along with the
extra macro definitions specified by POSIX. If you want to write POSIX
code and rely on the POSIX-specified c89 or c99 utility, and it acts as a
wrapper for gcc, it will add the -ansi (or -std=c99) and -pedantic options
anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top