Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Re: C language portability support
"Mike Wahler" <mkwahler@mkwahler.net> wrote:
> "asm" <arut@post.com> wrote: 

"typedef" is just a way of naming an arbitrary abstract data type.  It
has nothing to do with portability per se (except that all C compilers
support it).  You may be thinking of "#ifdef" which you misheard from
some conversation.

> Yes, C has 'support' for portablility, in that it
> is by definition a portable, platform-independent language.

Excuse me, but C is *NOT* a platform-independent language.  It
specifically states in the ANSI standard that certain operations such
as the right shift of signed integers, or the signedness of char are
platform specific.  By the same token C is not a portable language.

Virtually every C compiler exposes important platform specific
functionality *by neccessity* and the vast majority of C programs
specifically leverage these extensions which makes them non-portable.

Compare this with Java, where the only way to make a non-portable Java
program is to chew through insane amounts of memory (different
platforms will fault at different times), or have a race condition
(different timings will cause the race condition to manifest in
different ways).

> However, one must follow the language rules in order to achieve said
> portability.

No real world programmers deliberately follow any "rules" that would
make a C program completely portable.  People may do so inadvertently
and usually if their program is completely trivial.  Remember that the
real purpose of the C language is for making UNIX-style command line
utilities.  Anything else you try to do with the language will, by
itself, usually lead you away from portability (just using floating
point on x86, where "double"s can have intermediate calculations of
either 64 or 80 bits depending on the compiler *version*), and just
ordinary "expected usage" (<isspace(0x80)> is UB, <int digit =
(char)cdig - '0';> is not portable) will drive you toward "platform
depdendence" with respect to the C language.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Report this thread to moderator Post Follow-up to this message
Old Post
Paul Hsieh
09-28-04 01:55 PM


Re: C language portability support
qed@pobox.com (Paul Hsieh) wrote in message news:<796f488f.0409231810.6904559e@posting.goog
le.com>...
> "Mike Wahler" <mkwahler@mkwahler.net> wrote: 
>
> "typedef" is just a way of naming an arbitrary abstract data type.  It
> has nothing to do with portability per se (except that all C compilers
> support it).  You may be thinking of "#ifdef" which you misheard from
> some conversation.

Are you being deliberately obtuse?  Whether it has anything to do with
portability "per se", it's widely used to aid portability.  The
current C standard even explicitly uses it for that purpose:

7.18.1.1 Exact-width integer types

1 The typedef name intN_t designates a signed integer type with
width N.  Thus, int8_t denotes a signed integer type with a
width of exactly 8 bits.

2 The typedef name uintN_t designates an unsigned integer type
with width N.  Thus, uint24_t denotes an unsigned integer type
with a width of exactly 24 bits.

> 
>
> Excuse me, but C is *NOT* a platform-independent language.  It
> specifically states in the ANSI standard that certain operations such
> as the right shift of signed integers, or the signedness of char are
> platform specific.  By the same token C is not a portable language.
>
> Virtually every C compiler exposes important platform specific
> functionality *by neccessity* and the vast majority of C programs
> specifically leverage these extensions which makes them non-portable.
>

What's your point?  C can be used to write portable programs that can
run on anything from the largest supercomputers to tiny
microcontrollers.  It can also be used to write hideously unportable
programs that break every time the compiler vendor issues a point
release.

> Compare this with Java, where the only way to make a non-portable Java
> program is to chew through insane amounts of memory (different
> platforms will fault at different times), or have a race condition
> (different timings will cause the race condition to manifest in
> different ways).

To me, C is *much* more portable than Java.  There are many, many
platforms out there that do not have anything even remotely
approximating a Java runtime, but have a competent C compiler.

> 
>
> No real world programmers deliberately follow any "rules" that would
> make a C program completely portable.  People may do so inadvertently
> and usually if their program is completely trivial.  Remember that the
> real purpose of the C language is for making UNIX-style command line
> utilities.
<snip>

Now you're just being silly.  You follow the portability rules as much
as possible, and isolate platform specific code as much as possible.
Avoid undefined behavior, and isolate implementation defined behavior.

I suppose you'll find some reason that does not qualify as a "rule".


Mark F. Haigh
mfhaigh@sbcglobal.net

Report this thread to moderator Post Follow-up to this message
Old Post
Mark F. Haigh
09-28-04 01:55 PM


Re: C language portability support
In <lnvfdz2t30.fsf@nuthaus.mib.org> Keith Thompson <kst-u@mib.org> writes:

>Dan.Pop@cern.ch (Dan Pop) writes: 
>
>Perhaps, but I think a lot of programmers would automatically
>associate the name "myDouble" with C's type "double".

That would be a downright foolish association: no point in
*unconditionally* renaming a C keyword.

>If I wanted to
>create typedefs for small and large floating-point types, regardless
>of what the C compiler chooses to call them, I might use terms like
>"small_float" and "large_float" to avoid confusion.

I can still see no confusion with mySingle and myDouble.  It is sheer
stupidity to assume anything a priori about a user defined identifier.

>A typedef whose name is too close to a predefined type name is
>probably either redundant (if it's for the same type) or confusing (if
>it isn't).

For you, maybe.  To me, it conveys the message: this type is, in most
cases, the same as the C type with a similar name, but it can be something
else on unusual implementations.  See again my example with myDouble
ending up as being defined as long double on an exotic implementation,
while being defined as double on most other implementations.

>To take another example, "typedef unsigned char byte;" is more
>reasonable than "typedef unsigned char uchar;", IMHO.

To me, they are both unreasonable, being mere aliases for standard C
types.  When I read C code, I'm much happier if I don't have to deal with
such devices (despite the obvious semantics, such typedef's MUST be
checked, to be *sure* that they really are what they appear to be).

>(One might
>argue that "typedef unsigned char byte;" is redundant, but I might use
>such a typedef to distinguish between an unsigned char holding a
>character value and an unsigned char holding a fundamental unit of
>storage, a distinction that C's type system, for convoluted historical
>reasons, doesn't make very well.)

The actual distinction is made by using the type char for dealing with
character values and the type unsigned char for dealing with bytes.
This is why the type char hasn't been made obsolete after the introduction
of the types signed char and unsigned char.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan.Pop@ifh.de
Currently looking for a job in the European Union

Report this thread to moderator Post Follow-up to this message
Old Post
Dan Pop
09-28-04 01:55 PM


Re: C language portability support
mfhaigh@sbcglobal.net (Mark F. Haigh) wrote:
> qed@pobox.com (Paul Hsieh) wrote: 
>
> Are you being deliberately obtuse?  Whether it has anything to do with
> portability "per se", it's widely used to aid portability.

You mean the typedefs used header files for some C compilers?  This is
a very marginal claim about creating portability.  And more to the
point you typically can't use the include files from one compiler in
another.  When you have platform specific functionality which you want
to expose in a portable way, you end up having to leverage #ifdef's in
combination with already existing portable interfaces.  There's no
sense in which you rely in particular on typedef, other than using it
to potentially expose a common naming.

> [...] The
> current C standard even explicitly uses it for that purpose:
>
>     7.18.1.1 Exact-width integer types
>
>     1 The typedef name intN_t designates a signed integer type with
>       width N.  Thus, int8_t denotes a signed integer type with a
>       width of exactly 8 bits.
>
>     2 The typedef name uintN_t designates an unsigned integer type
>       with width N.  Thus, uint24_t denotes an unsigned integer type
>       with a width of exactly 24 bits.

What the hell has this got to do with portability?  First of all its
in reference to a C standard that is not widely adopted at all.  So in
fact use of intN_t will specifically destroy any chance of
portability.  Secondly, integers in C don't have a predescribed
implementation (like 2s complement, for example), so the int16_t on
one platform doesn't have to behave the same way as it might on any
other platform (except maybe having the same "sizeof").
 
>
> What's your point?  C can be used to write portable programs that can
> run on anything from the largest supercomputers to tiny
> microcontrollers.  It can also be used to write hideously unportable
> programs that break every time the compiler vendor issues a point
> release.

The point is that there is no clear dividing line between these two
classes of programs in C.  And the vast majority of the functionality
of your platform will mostly be in these non-portable extensions.
 
>
> To me, C is *much* more portable than Java.  There are many, many
> platforms out there that do not have anything even remotely
> approximating a Java runtime, but have a competent C compiler.

You are confusing availability with portability.  By this reasoning
assembly/machine language is even more portable since you have to
start there to bootstrap any C compiler.

To the best of my knowledge, in fact, there are no two C compilers in
existence which are portable with each other (Intel C++ and MSVC are
close since they actually share libraries and include files, but each
contains different semantics and extensions).  By contrast there are
no two Java compilers/implementation which are *not* portable (modulo
bugs).
 
> <snip>
>
> Now you're just being silly.  You follow the portability rules as much
> as possible, and isolate platform specific code as much as possible.
> Avoid undefined behavior, and isolate implementation defined behavior.
>
> I suppose you'll find some reason that does not qualify as a "rule".

No, my claim is that such rules are just not followed.  Who the hell
rigorously test for signedness independence of "char"?  C specifically
says that char can be either signed or unsigned.  And who keeps track
of the difference between POSIX and ANSI?  And if you are doing heavy
floating point, you can't do anything to isolate such platform
specific behaviors.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Report this thread to moderator Post Follow-up to this message
Old Post
Paul Hsieh
09-28-04 08:55 PM


Re: C language portability support
Chris Torek <nospam@torek.net> wrote:
> Paul Hsieh <qed@pobox.com> wrote: 
>
> But good real-world C programmers will often follow many "rules" that
> will make their C programs far more portable than if they fail to
> follow them.
> 
>
> Sensible people do so deliberately.

But my point is that they *fail*.  The reason is simple -- the code
continues to work and is correct for their platform even as they drift
to non-portability.  So there is no feedback mechanism by which a
programmer can realize that what they are doing is non-portabile.
Compare this to Java, where there is no choice about portability --
its just is.
 
>
> "Complete" portability will indeed only result for a quite limited
> subset of "all possible C programs", but not all such programs
> should be labeled "trivial", in my opinion.  (For instance, yacc/bison
> and lex/flex are not "trivial", yet can be written entirely in
> portable C.)

I said *usually*.  Later on in my post I also made mention of UNIX
command line utilities (which include yacc/bison.)
 
>
> True enough -- but the same problem occurs in other languages as
> well.  The x86 in particular is especially troublesome, because
> "fast" code invariably leaves values inside the FPU, where they
> have "too much" precision, even if you use precision-control code
> to fiddle with the FPU control word.  (In particular, the exponent
> is always held in 80-bit format, even when the mantissa is rounded,
> so that single and double precision values do not overflow to
> infinity correctly.)

This not exactly a correct characterization of the x86.  The x86 has a
64bit "mode flag" which, in fact, has been turned on in the modern x86
compilers.  The problem is with the C *STANDARD* that says x86
compilers could do whatever they want (and did, since in the early 90s
the extra precision was seen as an advantage).

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Report this thread to moderator Post Follow-up to this message
Old Post
Paul Hsieh
09-28-04 08:55 PM


Re: C language portability support
Paul Hsieh wrote:

> "typedef" is just a way of naming an arbitrary abstract data type.

If you are *really* concerned about portability,
none of the built-in types should appear in the body of your code.
Instead, you should substitute your own type definitions
for all of the built-in types -- in a header file:

typedef	int	myInteger;
typedef float	mySingle;
typedef double	myDouble;
typedef size_t	myExtent;
// etc.
#define myIntegerMax INT_MAX
// etc.

Remember that
portability is *not* about writing code that compiles everywhere.
It's about writing code that is easy to modify
for each target platform.
The best strategy is to *sequester* platform dependent code
into header files and subprograms
that are easy to locate and modify or replace.

Report this thread to moderator Post Follow-up to this message
Old Post
E. Robert Tisdale
09-28-04 08:55 PM


Re: C language portability support
>Chris Torek wrote: 

In article <news:4154934D.5DB3@mindspring.com>
pete  <pfiland@mindspring.com> wrote:
>I think (int) would be a better cast, if a cast is needed.

The cast is indeed not needed at all; I used "char" simply because that
was the original example I was quoting.

Note that while it *is* OK to assume that the digit-characters '0'
through '9' are contiguous and sequential -- i.e., '0' + 1 gives '1',
'1' + 1 gives '2', and so on through '8' + 1 == '9' -- it is *not*
OK, in terms of C portability, to assume that the same holds for
alphabetic characters.  In particular, EBCDIC (used on some IBM
mainframe machines for instance) has gaps between 'I' and J', and
again beween 'R' and 'S': while 'H' + 1 gives 'I', you then have
to add 7 or 8 (I forget which) to 'I' to get 'J'.

Again, it is not *wrong* to simply "assume ASCII", but it does
limit portability.  If the tradeoff you gain (whoever "you" may be
at the time, and whatever it is you gain) is worth the loss in
portability (however large or small you may think it is), go ahead
and give up the portability.  Just be aware that you are making
the assumption "this system uses ASCII", and if possible, document
it or test for it.

(These days one might even want to "assume Windows character set Q"
or "assume UTF-8" or some such, in various applications.  Just be
aware that not every system has these things.  If you *need* them,
you need them, and you have to discard portability in that part of
the program.  If you can isolate the non-portable parts of the code
from the portable parts, that will help when it comes time to port
the program.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
email: forget about it   http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

Report this thread to moderator Post Follow-up to this message
Old Post
Chris Torek
09-28-04 08:55 PM


Re: C language portability support
In article <news:796f488f.0409231810.6904559e@posting.google.com>
Paul Hsieh <qed@pobox.com> wrote:
>No real world programmers deliberately follow any "rules" that would
>make a C program completely portable.

But good real-world C programmers will often follow many "rules" that
will make their C programs far more portable than if they fail to
follow them.

>People may do so inadvertently

Sensible people do so deliberately.

>and usually if their program is completely trivial.

"Complete" portability will indeed only result for a quite limited
subset of "all possible C programs", but not all such programs
should be labeled "trivial", in my opinion.  (For instance, yacc/bison
and lex/flex are not "trivial", yet can be written entirely in
portable C.)

>... Anything else you try to do with the language will, by
>itself, usually lead you away from portability (just using floating
>point on x86, where "double"s can have intermediate calculations of
>either 64 or 80 bits depending on the compiler *version*),

True enough -- but the same problem occurs in other languages as
well.  The x86 in particular is especially troublesome, because
"fast" code invariably leaves values inside the FPU, where they
have "too much" precision, even if you use precision-control code
to fiddle with the FPU control word.  (In particular, the exponent
is always held in 80-bit format, even when the mantissa is rounded,
so that single and double precision values do not overflow to
infinity correctly.)

>and just ordinary "expected usage" (<isspace(0x80)> is UB, <int digit =
>(char)cdig - '0';> is not portable)

The isspace() function is defined over the domain union{EOF,
all_possible_unsigned_chars}, and UCHAR_MAX must be at least 0xff.
Since 0x80 (128) is between 0 and 255 inclusive, isspace(128) is
well-defined.

Likewise, if "cdig" is a value in '0' through '9', the line:

int digit = (char)cdig - '0';

is guaranteed to set digit to 0 through 9 correspondingly.  Moreover,
if you write instead:

unsigned int digit = (unsigned)cdig - '0';

you can then test whether cdig was a valid digit character:

if (digit > 9)
printf("%c was not a valid digit\n", cdig);

also with complete portability (given UCHAR_MAX <= UINT_MAX and
the rules for unsigned arithmetic).

There is nothing inherently wrong with using platform- or
machine-dependent code in C programs, of course.  But comp.lang.c
is not the best place to talk about such code; instead, here we
can talk about how to *avoid* such code if and when it is reasonable
to do so (e.g., when dealing with text files, rather than graphical
interfaces).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
email: forget about it   http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

Report this thread to moderator Post Follow-up to this message
Old Post
Chris Torek
10-02-04 01:55 PM


Re: C language portability support
"Paul Hsieh" <qed@pobox.com> wrote
>
> No real world programmers deliberately follow any "rules" that would
> make a C program completely portable.  People may do so inadvertently
> and usually if their program is completely trivial.
>
You are confusing "trivial" with "doesn't manipulate hardware". A large
number of programs use a GUI, or network, or similar, however not all,
particularly if you are writing scientific or similar programs. Often the
only "non-portable" feature needed is directory support.
Also, a lot of programs have inherently portable components. For instance a
spell-checker is most useful when integrated with a wordprocessor, but the
routine itself neden't have any platform dependencies.



Report this thread to moderator Post Follow-up to this message
Old Post
Malcolm
10-02-04 01:55 PM


Re: C language portability support
On 25 Sep 2004 21:24:50 -0700, qed@pobox.com (Paul Hsieh) wrote:

> mfhaigh@sbcglobal.net (Mark F. Haigh) wrote:
<snip> 
>
> What the hell has this got to do with portability?  First of all its
> in reference to a C standard that is not widely adopted at all.  So in
> fact use of intN_t will specifically destroy any chance of
> portability.  Secondly, integers in C don't have a predescribed
> implementation (like 2s complement, for example), so the int16_t on
> one platform doesn't have to behave the same way as it might on any
> other platform (except maybe having the same "sizeof").
>
C integer types in general aren't required to be 2sc, although
hardware where they aren't is very rare indeed. But the exact-width
types in particular, int<N>_t IF PROVIDED (which is not required) must
be 2sc and (uint<N>_t also) have no padding. Signed overflow (and
negative rightshift) are still up to the implementation.  And they
*aren't* required to have to the same sizeof, presumably 2, since a
platform with CHAR_BIT 16 and sizeof(int16_t) == 1 is perfectly legal.

- David.Thompson1 at worldnet.att.net

Report this thread to moderator Post Follow-up to this message
Old Post
Dave Thompson
10-04-04 08:55 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

C archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 04:17 AM.

 

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.