[comp.std.c] Frustrated trying to be portable

clgreen@nsslsun.gcn.uoknor.edu (Cliff Green) (02/18/91)

I'm getting somewhat frustrated in making a fairly complex package I'm working
on to be portable.  I've worked on large software projects for years, but this
is the first one that I'm trying to make portable between various hardware and
os's (Unix, VMS on VAXen, Sun, SGI, etc.).  Quickly realizing the uses of ANSI
C, I ordered the standard (thanks, FAQ) and had the sysadmin on our Suns 
install a copy of GCC.  VAX C seems to be pretty close in most of the basic
aspects of the standard, but there still seems to be a lot missing in regards
to the C library calls using the GCC compiler (with the gcc-include directory).
I would like all the standard include files complete with the standard
function prototypes (I'm a big believer in prototyping) and the standard
library functions themselves.  Specifically on the Sun I'm missing:
  stdlib    include file (kind of important, to say the least)
  remove    function (I shouldn't have to #define remove  unlink)
  strerror  function (I like setting up my own error handling/message catalogs)

Anyway, am I missing something, or is the state of ANSI C compilers still in a
formative stage?  I've gotten around all these problems with #ifdef statements,
but that nullifies the whole idea of a standard, doesn't it?  I appreciate all
the help you can give this standards novice.

Cliff Green
clgreen@nsslsun.gcn.uoknor.edu     (405) 366-0470 (work)

steve@groucho.ucar.edu (Steve Emmerson) (02/18/91)

[I'm posting this article rather than replying via email due to the
general nature of the problem and the fact that our approach (detailed
below) might be incorrect.]

Cliff Green <clgreen@nsslsun.gcn.uoknor.edu> writes:

>I'm getting somewhat frustrated in making a fairly complex package I'm 
>working on to be portable.  ...

>...?  I appreciate all
>the help you can give this standards novice.

We're attempting to solve just this portability problem through the use
of platform- (i.e. operating-system and compiler) dependent header-files
and interface libraries.  For example, a program might have at its top

	#include "udposix.h"
	#include <stdlib.h>
	...

and, if necessary, we supply the <stdlib.h> header-file, which might
include system-supplied header files as well as defining/declaring any
missing items.  The coding style is a subset of that allowed by the
union of Standard C and POSIX.  Function prototypes are supported on
appropriate platforms.

The code would be compiled by something akin to

	cc -I$(UNIDATA_INC) <program>.c -L$(UNIDATA_LIB) -ludposix ...

where the `udposix' library is also supplied by us (it's empty on some
platforms).  Missing functions are created and incorporated into the
library on an as-needed basis.

Supported platforms include AIX 3.1, SunOS 4.0.3, SunOS 4.1, 
SunOS 4.1.1, Ultrix 3.5, Ultrix 4.0, UNICOS 5.1.9, and VMS 5.3.

If you'd like more information, give me a buzz.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (02/19/91)

In <1991Feb17.203337.20569@uokmax.ecn.uoknor.edu>
clgreen@nsslsun.gcn.uoknor.edu (Cliff Green) writes:

     I'm getting somewhat frustrated in making a fairly complex package
     I'm working on to be portable....I'm trying to make portable
     between various hardware and os's (Unix, VMS on VAXen, Sun, SGI,
     etc.).

Good!  Portability is a worthwhile goal.

     Quickly realizing the uses of ANSI C, I ordered the standard
     (thanks, FAQ) and had the sysadmin on our Suns install a copy of
     GCC.

Good!  Conformance to a standard is a worthwhile goal.

     VAX C seems to be pretty close in most of the basic aspects of the
     standard, but there still seems to be a lot missing...Specifically
     on the Sun I'm missing [some include files and functions].

And there's the rub!  You are trying to attain two mutually-exclusive
goals.  Today, given that we are in a transition between traditional C
and ANSI C, one of the best ways to be highly nonportable is to use
pure ANSI C.

So what can you do?  Try this:

1. Use a PARAMS or similar macro to enclose the argument list in
function prototypes in declarations.  Use traditional syntax for
function definitions.

2. Use a symbol STDINCLUDE.  If it's defined, include the ANSI standard
include files.  If not, include traditional C include files only.
Define it wisely.

     #ifdef STDINCLUDE
     # include <stdlib.h>
     # include <string.h>
     #else
       extern char *malloc();
       extern char *strcpy(), *strncpy(), *strcat();
       extern int strlen();
     #endif

(Do not use __STDC__ above -- it's quite possible for a C environment
that isn't strictly ANSI C to still provide ANSI C include files.)

3. If you need functions only provided by ANSI C, either write your own
for other environments.  For example, if you need memmove, use
move_down and move_up instead and include code like the following.
(Check the code for off-by-one errors before using it.)

     #ifdef NEED_MEMMOVE
       char *move_down(dest, src, len) char *dest, *src; unsigned len;
       { char *p = dest; while (len>0) { *dest++ = *src++; --len; } return p; }
       char *move_up(dest, src, len) char *dest, *src; int len;
       { char *p = dest; dest += len; src += len;
	 while (len > 0) { *dest-- = *src--; --len; } return p; }
     #else
     # define move_down   memmove
     # devine move_up     memmove
     #endif

The above hints are the ones that aren't well explained in standard
textbooks.  For many others, see books about portable C programming.
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

gwyn@smoke.brl.mil (Doug Gwyn) (02/19/91)

In article <1991Feb17.203337.20569@uokmax.ecn.uoknor.edu> clgreen@nsslsun.gcn.uoknor.edu (Cliff Green) writes:
>Anyway, am I missing something, or is the state of ANSI C compilers still
>in a formative stage?

It would be more accurate to say that the availability of such compilers
is still limited.

No compiler should be advertised as conforming to the (ANSI/ISO) C standard
unless it fully meets the requirements for a conforming implementation
specified in the standard.  There are two kinds of conforming implementation:
hosted and standalone.  The one you are interested in would be a conforming
hosted implementation.  Certainly such an implementation would have to
provide <stdlib.h>, remove(), etc.

richard@aiai.ed.ac.uk (Richard Tobin) (02/20/91)

In article <15240@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>No compiler should be advertised as conforming to the (ANSI/ISO) C standard
>unless it fully meets the requirements for a conforming implementation
>specified in the standard.

This is obviously true.

>There are two kinds of conforming implementation:
>hosted and standalone.  The one you are interested in would be a conforming
>hosted implementation.  Certainly such an implementation would have to
>provide <stdlib.h>, remove(), etc.

As far as I can tell, some of the library functions described in the
standard can be implemented portably (requiring in some cases a
particular operating system), whereas some others can't.  For example
the functions from <string.h> and <stdio.h> can, whereas those in
<stdarg.h> can't.

This isn't however the distinction between a hosted and freestanding
implementation, since a freestanding implementation doesn't have to
provide <setjmp.h> and perhaps other non-portable libraries.

A compiler that provided only the non-portably-implementable library
functions (and headers) might well be very useful in a hosted
environment.

-- Richard
-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

gwyn@smoke.brl.mil (Doug Gwyn) (02/20/91)

In article <4188@skye.ed.ac.uk> richard@aiai.UUCP (Richard Tobin) writes:
>As far as I can tell, some of the library functions described in the
>standard can be implemented portably (requiring in some cases a
>particular operating system), whereas some others can't.  For example
>the functions from <string.h> and <stdio.h> can, whereas those in
><stdarg.h> can't.

Requiring a particular operating system is hardly a "portable"
implementation.  It is not clear to me that ANY of the standard
library packages specific to a hosted environment can be
implemented perfectly portably.  In any case, the question was
about compilers that apparently were advertised as supporting
"ANSI C".  Hosted vs. freestanding conforming implementations
are the only two sensible categories that chould be so advertised.
An implementation of either category can of course include
additional functionality beyond that specified for the category
in the C standard, subject only to some fairly mild constraints.

steve@taumet.com (Stephen Clamage) (02/21/91)

richard@aiai.ed.ac.uk (Richard Tobin) writes:

|As far as I can tell, some of the library functions described in the
|standard can be implemented portably ... whereas some others can't....

|A compiler that provided only the non-portably-implementable library
|functions (and headers) might well be very useful in a hosted
|environment.

Why would it be useful?  If you wanted to use the remainder of the
standard functions, you would have to write or acquire source for them,
or hope that their implementation in the binary library supplied with
some other compiler would work.  I fail to see a market for such a
grossly incomplete implementation.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

henry@zoo.toronto.edu (Henry Spencer) (02/21/91)

In article <4188@skye.ed.ac.uk> richard@aiai.UUCP (Richard Tobin) writes:
>As far as I can tell, some of the library functions described in the
>standard can be implemented portably (requiring in some cases a
>particular operating system), whereas some others can't.  For example
>the functions from <string.h> and <stdio.h> can...

I haven't studied <stdio.h>, but you need to look more closely at <string.h>
before making such statements. :-)  It is not possible to implement memmove(),
in particular, in portable C.  (Hint:  think about pointer comparisons.)
-- 
"Read the OSI protocol specifications?  | Henry Spencer @ U of Toronto Zoology
I can't even *lift* them!"              |  henry@zoo.toronto.edu  utzoo!henry

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (02/22/91)

In <1991Feb20.175318.28496@zoo.toronto.edu> henry@zoo.toronto.edu
(Henry Spencer) writes:

     It is not possible to implement memmove(), in particular, in
     portable C.

This is unfortunately true.  My portable solution, is to assume that
the caller of memmove() always knows the direction of the move.   The
caller should therefore call either move_down() or move_up(), making
the same sort of decision about direction of the move that memmove()
would make anyway.  And move_down() and move_up() *can* be portably
implemented.  Lazy ANSI-conformant implementors can still do:

     #define move_down   memmove
     #define move_up     memmove
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

rns@tortuga.SanDiego.NCR.COM (Rick Schubert) (02/23/91)

In article <1991Feb20.175318.28496@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>In article <4188@skye.ed.ac.uk> richard@aiai.UUCP (Richard Tobin) writes:
>I haven't studied <stdio.h>, but you need to look more closely at <string.h>
>before making such statements. :-)  It is not possible to implement memmove(),
>in particular, in portable C.  (Hint:  think about pointer comparisons.)

I think it's been stated before that memmove() cannot be implemented in
portable C, but now that I think about it, I don't think that's strictly
true.  It IS true that the relational operators cannot be used to compare
the 2 pointer arguments to memmove() (since they may, and probably do,
point to different objects), but the equality operators may be
used to compare such pointers.  Given the prototype:
            void *memmove(void *s1, const void *s2, size_t n);
if the objects pointed to by |s1| and |s2| overlap, then either |s1|
is one of the |n| bytes pointed at% by |s2| (in which case the copy should
start at |(char *)s2 + n - 1| and proceed backward), or |s2| is
one of the |n| bytes pointed at by |s1| (in which case the copy should
start at |(char *)s2| and proceed forward).  Each of these conditions
can be determined with at most |n| pointer-equality comparisons.

I'm not necessarily recommending such an implementation; it's just that
it can be done portably.

As far as <stdio.h> is concerned, I don't think you can get very far without
some primitive I/O facilities.  Since the C language itself (outside of the
<stdio.h> library) has no I/O facilities, there is no way to do any I/O
in the <stdio.h> library without calling another <stdio.h> function or
calling a system-specific I/O routine.  Or am I missing something?

% Chris Torek: Did I use "point at" correctly?

-- Rick Schubert (rns@tortuga.SanDiego.NCR.COM)

peter@ficc.ferranti.com (Peter da Silva) (02/26/91)

In article <2960@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
> [You can't implement it portably].  My portable solution, is to assume that
> the caller of memmove() always knows the direction of the move.

Are you sure? Either one of two situations exists:

	The pointers are into the same object.
	The pointers are into different objects.

In the former case, overlap is a problem but you can compare them for
magnitude. In the latter case, overlap is not a problem. The result of
comparing two pointers into different objects is undefined but when you
don't care about the result why worry?

(or is this one of those cases where "undefined" means "run nethack"?)
-- 
Peter da Silva.  `-_-'  peter@ferranti.com
+1 713 274 5180.  'U`  "Have you hugged your wolf today?"

rfg@NCD.COM (Ron Guilmette) (02/26/91)

In article <2956@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
>In <1991Feb17.203337.20569@uokmax.ecn.uoknor.edu>
>
>2. Use a symbol STDINCLUDE.  If it's defined, include the ANSI standard
>include files.  If not, include traditional C include files only.
>Define it wisely.
>
>     #ifdef STDINCLUDE
>     # include <stdlib.h>
>     # include <string.h>
>     #else
>       extern char *malloc();
>       extern char *strcpy(), *strncpy(), *strcat();
>       extern int strlen();
>     #endif
>
>(Do not use __STDC__ above -- it's quite possible for a C environment
>that isn't strictly ANSI C to still provide ANSI C include files.)

It occurs to me that the x3j11 committee messed up by allowing there to
be two *different* but equally *legal* variants of "ANSI C" (i.e.
standalone and hosted) without providing users with any mandated (and
reliable) way to differentiate between these two variants of "ANSI C".

It would have been nicer if the x3j11 committee had *required* there to
be an additional symbol defined (e.g. __HOSTED_STDC__) *only* for "hosted"
implementations.

Why wasn't this done?

Now that this mistake has been made, is there any "common practice" or
defacto standard method by which a program can check to see if it is being
compiled by/within a "hosted" implementation or a "standalone" implementation?

If not, I'd like to propose that ANSI C compilers should define the extra
symbol __HOSTED_STDC__ if they are part of a "hosted" implementation.  I'm
proposing only that ANSI C implementors should try to make this a common
practice.  It's too late now to go back and change the ANSI C standard.

-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

gwyn@smoke.brl.mil (Doug Gwyn) (02/27/91)

In article <4108@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>Why wasn't this done?

It wasn't necessary.

>Now that this mistake has been made, is there any "common practice" or
>defacto standard method by which a program can check to see if it is being
>compiled by/within a "hosted" implementation or a "standalone" implementation?

It isn't necessary.  If the application requires library functions
that are required for a hosted implementation but not for a
freestanding implementation, then it couldn't survive being told
that it is being compiled by a freestanding implementation anyway.

peter@ficc.ferranti.com (Peter da Silva) (02/28/91)

> It isn't necessary.  If the application requires library functions
> that are required for a hosted implementation but not for a
> freestanding implementation, then it couldn't survive being told
> that it is being compiled by a freestanding implementation anyway.

---------- complex_utility_routine.c
#ifdef HOSTED
	compile a bunch of journalling code for debugging in
	the hosted version
#else
	compile a bunch of stubs
#endif
-- 
Peter da Silva.  `-_-'  peter@ferranti.com
+1 713 274 5180.  'U`  "Have you hugged your wolf today?"

rfg@NCD.COM (Ron Guilmette) (03/03/91)

In article <15333@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
+In article <4108@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
+>Now that this mistake has been made, is there any "common practice" or
+>defacto standard method by which a program can check to see if it is being
+>compiled by/within a "hosted" implementation or a "standalone" implementation?
+
+It isn't necessary.  If the application requires library functions
+that are required for a hosted implementation but not for a
+freestanding implementation, then it couldn't survive being told
+that it is being compiled by a freestanding implementation anyway.

I think that you have just assumed away a very real problem.

Look.  I have a program which can work, and which can do useful things
even within an environment which only conforms to "standalone" subset
of ANSI C.

However I can also get that program to do more things (or better things,
or different things) if I happen to be compiling it within an environment
which qualifies as a full-blown "hosted" implementation of ANSI C.

Unfortunately, x3j11 didn't provide any standard mechanism for the compiler
(or the preprocessor) to tell the program what sort of "standard" C
environment it is being compiled in, so what I have to do (in lieu of
such a feature) is to give this program to various people and instruct
them each to find out if they have a full-blown "hosted" implementation
or only a paltry "standalone" implementation and then to manually edit
the makefile and either include or dis-include -D__HOSTED_STDC__ in CFLAGS
depending upon the specifics of their implementation.

I wish that I did't have to do all that.

-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.

henry@zoo.toronto.edu (Henry Spencer) (03/03/91)

In article <N4Q94O2@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
>In the former case, overlap is a problem but you can compare them for
>magnitude. In the latter case, overlap is not a problem. The result of
>comparing two pointers into different objects is undefined but when you
>don't care about the result why worry?
>
>(or is this one of those cases where "undefined" means "run nethack"?)

"Undefined" *always* means "might run nethack", "might call your boss and
report you for incompetence", "might phone an anonymous tip to the FBI that
you're running dope to Saddam Hussein", etc.  Portable programs must avoid
ever encountering such situations.
-- 
"But this *is* the simplified version   | Henry Spencer @ U of Toronto Zoology
for the general public."     -S. Harris |  henry@zoo.toronto.edu  utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (03/03/91)

In article <N4Q94O2@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
-In article <2960@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
-> [You can't implement it portably].  My portable solution, is to assume that
-> the caller of memmove() always knows the direction of the move.
-Are you sure? Either one of two situations exists:
-	The pointers are into the same object.
-	The pointers are into different objects.
-In the former case, overlap is a problem but you can compare them for
-magnitude. In the latter case, overlap is not a problem. The result of
-comparing two pointers into different objects is undefined but when you
-don't care about the result why worry?

Because any reliance on undefined behavior is obviously not portable,
as the man said.  In fact for a wide class of architectures, there is
no problem, but for some architectures the C run-time implementation
may trap on an attempt to compare two pointers to different objects.

jfh@rpp386.cactus.org (John F Haugh II) (03/04/91)

In article <4204@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>In article <15333@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>+It isn't necessary.  If the application requires library functions
>+that are required for a hosted implementation but not for a
>+freestanding implementation, then it couldn't survive being told
>+that it is being compiled by a freestanding implementation anyway.
>
>I think that you have just assumed away a very real problem.
>
>Look.  I have a program which can work, and which can do useful things
>even within an environment which only conforms to "standalone" subset
>of ANSI C.

I have to side with Ron on this one.  Doug is making the assumption
that the functions =must= exist for the program to be executed.  Yet
there were quite a few commands, such as 'ls', which have traditionally
been compiled "standalone" and "hosted" that managed to function quite
well long before the arrival of ANSI C.  Anyone with access to the old
source to "ls" can go see for themselves what I am talking about.

The standalone C library provided a great many functions which also
existed in the "real" C library, yet many, such as "getpid()", were
little more than stubs.  I've not compiled a standalone anything in a
while, but as I recall, the standalone C compiler defined the macro
"STANDALONE" when it was being used.
-- 
John F. Haugh II        | Distribution to  | UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832 | GEnie PROHIBITED :-) |  Domain: jfh@rpp386.cactus.org
"I've never written a device driver, but I have written a device driver manual"
                -- Robert Hartman, IDE Corp.

pab@cs.arizona.edu (Peter A. Bigot) (03/04/91)

In article <19085@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
> In article <4204@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
> >In article <15333@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
> >+It isn't necessary.  If the application requires library functions
> >+that are required for a hosted implementation but not for a
> >+freestanding implementation, then it couldn't survive being told
> >+that it is being compiled by a freestanding implementation anyway.
> >
> >I think that you have just assumed away a very real problem.
> >
> >Look.  I have a program which can work, and which can do useful things
> >even within an environment which only conforms to "standalone" subset
> >of ANSI C.
> 
> I have to side with Ron on this one.  Doug is making the assumption
> that the functions =must= exist for the program to be executed.  Yet
> there were quite a few commands, such as 'ls', which have traditionally
> been compiled "standalone" and "hosted" that managed to function quite
> well long before the arrival of ANSI C.  Anyone with access to the old
> source to "ls" can go see for themselves what I am talking about.

Although I don't have access to source to ls, I very much doubt that it's
conformant wrt an ANSI free-standing compiler, given that such a beast is not
obligated to provide _any_ library functions, let alone the "standard" ones.
Virtually no useful program is portable except in a hosted environment--how are
you going to do i/o?  Standalone is good for embedded controllers; that's about
it.

A hosted environment is required only to provide those library functions (all
of them) in section 4 of the "bible".  So I've got this neat program that needs
to call another, and I want it portable.  For a regular hosted environment, I
can call the system() function, wait for the return, and get my results that
way (although what they are is implementation defined).  But if I'm running
under Unix, I can fork and exec, and keep on working, picking up the results
later on.  Both are (with luck) hosted environments, and under the suggested
scheme, both would define __HOSTED_STDC__ (or whatever), but I wouldn't be able
to tell from that which block of code should be compiled.

What we _really_ want then, is some convention to let us know what class of
additional functions are provided in this particular implementation of a hosted
compiler; e.g., __POSIX_STDC__ or some such.  _That_ I'd vote for; but it's a
convention, not something that should be mandated by the language standard.

Peter
-- 
                     Peter A. Bigot -- pab@cs.arizona.edu
          Dept. of Computer Science, University of Arizona, Tucson AZ
---------------------------- The current quote is: ----------------------------
"What is this, again?" "Art." "Oh, yeah."  Lady Sarah Ferguson, the Duchess of
York (on being shown a steel shipping container supported by Barbie dolls).

gwyn@smoke.brl.mil (Doug Gwyn) (03/05/91)

In article <19085@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
>In article <4204@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>>In article <15333@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>>+It isn't necessary.  If the application requires library functions
>>+that are required for a hosted implementation but not for a
>>+freestanding implementation, then it couldn't survive being told
>>+that it is being compiled by a freestanding implementation anyway.
>>I think that you have just assumed away a very real problem.
>>Look.  I have a program which can work, and which can do useful things
>>even within an environment which only conforms to "standalone" subset
>>of ANSI C.
>I have to side with Ron on this one.  Doug is making the assumption
>that the functions =must= exist for the program to be executed.  Yet
>there were quite a few commands, such as 'ls', which have traditionally
>been compiled "standalone" and "hosted" that managed to function quite
>well long before the arrival of ANSI C.  Anyone with access to the old
>source to "ls" can go see for themselves what I am talking about.

In fact I am well aware of AT&T's "standalone" mode for a few commands
such as "ls", and how they are used.  On the other hand, I don't think
you have thought this matter through very well.  If you have an
application that performs useful work in a "freestanding" C environment,
it must directly access hardware registers or be linked with some
nonstandard support library in order to perform I/O etc.  Obviously this
would not be a portable application.  Being nonportable, it can and
would take advantage of system-specific support.  There is nothing to
keep you from using such "hosted" functions as can be made to work in
such an environment.  You don't need to key on any implementation-
provided macro for this, either.

If you think that a single UNIVERSAL macro would have made this a whole
lot easier that it happens to normally be, you are dreaming.  There is
a lot more than that necessary to configure applications to operate in
a multiplicity of non-hosted environments.

gwyn@smoke.brl.mil (Doug Gwyn) (03/05/91)

In article <15938.27d2c9d3@levels.sait.edu.au> xtdn@levels.sait.edu.au writes:
>> for some architectures the C run-time implementation
>> may trap on an attempt to compare two pointers to different objects.
>Does this include == and !=, or just the other inequalities?

The C standard requires that the exact equality test work in such a case;
X3J11 was willing to require the additional "normalization" of pointers
for that case, but not for general relational tests of pointers.

xtdn@levels.sait.edu.au (03/05/91)

gwyn@smoke.brl.mil (Doug Gwyn) writes:
> In article <N4Q94O2@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
> -The result of comparing two pointers into different objects is undefined
> -but when you don't care about the result why worry?
[...]
> for some architectures the C run-time implementation
> may trap on an attempt to compare two pointers to different objects.

Does this include == and !=, or just the other inequalities?


David Newall, who no longer works       Phone:  +61 8 344 2008
for SA Institute of Technology          E-mail: xtdn@lux.sait.edu.au
                "Life is uncertain:  Eat dessert first"

jfh@rpp386.cactus.org (John F Haugh II) (03/05/91)

In article <15382@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In fact I am well aware of AT&T's "standalone" mode for a few commands
>such as "ls", and how they are used.  On the other hand, I don't think
>you have thought this matter through very well.  If you have an
>application that performs useful work in a "freestanding" C environment,
>it must directly access hardware registers or be linked with some
>nonstandard support library in order to perform I/O etc.  Obviously this
>would not be a portable application.  Being nonportable, it can and
>would take advantage of system-specific support.  There is nothing to
>keep you from using such "hosted" functions as can be made to work in
>such an environment.  You don't need to key on any implementation-
>provided macro for this, either.

Sure you do.  How else do you key on the fact that your otherwise
portable application requires otherwise nonportable or special
support?  That is, what is the portable mechanism for saying that
you are in need of non-standard support?

Or are you saying that unless it can be handled portably in every
environment then it shouldn't be handled by ANSI C?  Because if
that is the case, we might as well chuck the language now and go
make up something more reflective of the real world.

>If you think that a single UNIVERSAL macro would have made this a whole
>lot easier that it happens to normally be, you are dreaming.  There is
>a lot more than that necessary to configure applications to operate in
>a multiplicity of non-hosted environments.

Who does the language serve?  Why was "#ifdef unix" ever useful?

I'm not saying include every marginally useful feature, but I am
suggesting that there are some "marginal" features that are less
"marginal" than others.
-- 
John F. Haugh II        | Distribution to  | UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832 | GEnie PROHIBITED :-) |  Domain: jfh@rpp386.cactus.org
"I've never written a device driver, but I have written a device driver manual"
                -- Robert Hartman, IDE Corp.

rfg@NCD.COM (Ron Guilmette) (03/10/91)

In article <19085@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
|In article <4204@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
|>In article <15333@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
|>+It isn't necessary.  If the application requires library functions
|>+that are required for a hosted implementation but not for a
|>+freestanding implementation, then it couldn't survive being told
|>+that it is being compiled by a freestanding implementation anyway.
|>
|>I think that you have just assumed away a very real problem.
|>
|>Look.  I have a program which can work, and which can do useful things
|>even within an environment which only conforms to "standalone" subset
|>of ANSI C.
|
|I have to side with Ron on this one...

I just wanted to let it be known that I certainly didn't mean to start
choosing up sides.  If we are going to do that, I think I wanna be on
Doug Gwyn's team.  He's an awfully knowledgeable guy when it comes to
ANSI C, and he has helped me many times by answering my (sometimes silly)
questions.

(I do reserve the right to start an occasional friendly disagreement with
him however.)
-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.

rfg@NCD.COM (Ron Guilmette) (03/10/91)

In article <31204@megaron.cs.arizona.edu> pab@cs.arizona.edu (Peter A. Bigot) writes:
>
>What we _really_ want then, is some convention to let us know what class of
>additional functions are provided in this particular implementation of a hosted
>compiler; e.g., __POSIX_STDC__ or some such.  _That_ I'd vote for; but it's a
>convention, not something that should be mandated by the language standard.

There are two important points I'd like to make here.

First, there are already conventions (or actually standards) estanblished
for the symbols that should get automatically defined in a true POSIX
environment.

Second, even if we consider the case that I was worried about (i.e. hosted
versus non-hosted) anything that might be done at this late date *must*
necessarily be only a "convention" (perhaps agreed upon my many many
implementors) because it is just too bloody late to change the ANSI C
standard.  (I for one would be satisfied with just a widespread convention
under which implementations would define __HOSTED_STDC__ if they qualified
as hosted implementations of ANSI C.)
-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.

rfg@NCD.COM (Ron Guilmette) (03/10/91)

In article <15382@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>
>In fact I am well aware of AT&T's "standalone" mode for a few commands
>such as "ls", and how they are used.  On the other hand, I don't think
>you have thought this matter through very well.  If you have an
>application that performs useful work in a "freestanding" C environment,
>it must directly access hardware registers or be linked with some...

The case that I was most concerned about (and the reason I raised the
issue of __HOSTED_STDC__) had nothing to do with embedded systems or
device registers or any low-level stuff like that.  No.  The case that
I was worried about was GCC on a Sun4 under SunOS 4.0.  In *that* (perhaps
rather common) case the compiler correctly defines __STDC__ to 1 because
the implementation meets the minimal criteria for a standalone implementation.

Now, if you are using this compiler in this environment, and you do:

	#ifdef __STDC__
	#include <stdio.h>
	#endif


	#ifdef __STDC__
			/* some use of `size_t' */
	#endif

you are going to get errors because although GCC is a minimally
compliant implementation of ANSI C, the environment it sits in rarely
includes a set of maximally compliant header files and libraries.

That's where having __HOSTED_STDC__ would come in handy.  If it were
defined, I could be assured that after <stdio.h> was included, I could
use the type size_t, whereas if __HOSTED_STDC__ were not defined, I might
write the code to play it safe and use something bland like `int' instead
of size_t.

I could name a few dozen more examples of places where Sun or DEC or
HP, or Motorola or Intel "system" header files (for various releases
of UNIX which these companies have made) are not quite right (or not
quite enough) to really get you up to a "complete" and "conformant"
hosted implementation of ANSI C.  So if you want more examples, just
let me know.

-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.