C, really portable?

P

pemo

Is C really portable? And, apologies, but this is possibly a little OT?



In c.l.c we often see 'not portable' comments, but I wonder just how
portable C apps really are.



I don't write portable C code - *not only* because, in a 'C sense', I
probably do things that aren't portable - but because for the last x years,
I've written code to run on a number of different platforms. Those apps
have had to make use of system calls, use threads, present nice UIs, .



Premise: any decently complex modern application cannot be entirely written
in standard C [meaning, the language without compiler added 'extensions',
and only using the standard libraries]. Or, if it is written in standard C,
then it is 'sub optimal' [and certainly doesn't have a nice UI!].



Conclusion: Whilst the language is portable, applications are not. And
that's why we also often see 'go and ask elsewhere' comments appearing here
[totally reasonable they are too of course].



Anyway, just a thought, and I wonder if anyone can come up with a counter to
it?
 
F

Flash Gordon

pemo said:
Is C really portable? And, apologies, but this is possibly a little OT?

C is very portable.
In c.l.c we often see 'not portable' comments, but I wonder just how
portable C apps really are.

90%[1] of most apps can be written in portable C leaving only 10% you
have to actually tailor for the target.
I don't write portable C code - *not only* because, in a 'C sense', I
probably do things that aren't portable - but because for the last x years,
I've written code to run on a number of different platforms. Those apps
have had to make use of system calls, use threads, present nice UIs, .

So you isolate those pieces of code in a system specific module.
Premise: any decently complex modern application cannot be entirely written
in standard C [meaning, the language without compiler added 'extensions',
and only using the standard libraries]. Or, if it is written in standard C,
then it is 'sub optimal' [and certainly doesn't have a nice UI!].

Certainly the bulk of applications have non-standard components, but
that does not mean the bulk of the code has to be non-standard.
Conclusion: Whilst the language is portable, applications are not. And
that's why we also often see 'go and ask elsewhere' comments appearing here
[totally reasonable they are too of course].

Many applications are very portable, requiring just a small amount of
tailoring for specific targets. This can be assisted by using libraries
that are available on multiple targets for the system specific stuff
(e.g. QT or GTK+).

I've written C for an embedded system that I then debugged on a silicon
graphics workstation (with some wrapper code) and some of the code was
then used on another completely different platform.

The code I'm currently working on is destined to run on Windows, Linux
and AIX (not in that order), and the application has previously run on
other systems.
Anyway, just a thought, and I wonder if anyone can come up with a counter to
it?

See above. Many of us here work on software that is required to run on
multiple platforms, and we use techniques that have been around since
before I started programming to do it. Things like modularisation and
keeping all the system specific stuff out of the bulk of the modules.

[1] 75% of all statistics are made up on the spot
 
R

Richard Heathfield

pemo said:
Is C really portable?

C isn't portable.
C programs aren't terribly portable - a bit, that's all.
C libraries can be *astoundingly* portable, if done properly.

C the language isn't any more or less portable than English.

Useful C programs can be written which will work in many environments, and
indeed I have written many such myself.

But where C really scores is in the fact that you can write a whole bundle
of stuff that will be useful on any platform whatsoever, and call it a
"library".
In c.l.c we often see 'not portable' comments, but I wonder just how
portable C apps really are.

If carefully written to abstract any non-portable parts of their
functionality into separate modules, C applications can be extraordinarily
portable. Take 500,000 lines of carefully written code, 5,000 of which are
carefully isolated platform-related stuff, and the rest of which is
straight ISO C. Rewrite those 5,000 every time you hit a new platform.
Takes about four man-weeks to port, instead of eight man-years. Hey presto,
portable Web browser. (Hi Borris.)
 
S

slebetman

pemo said:
Premise: any decently complex modern application cannot be entirely written
in standard C [meaning, the language without compiler added 'extensions',
and only using the standard libraries]. Or, if it is written in standard C,
then it is 'sub optimal' [and certainly doesn't have a nice UI!].

Well... yes since you often have to interact with the OS and
environment. But I don't re-write programs monolithically every time I
start a new project. I "drag&drop" libraries I've written over the
years and just write a new main file for the program.

Conclusion: Whilst the language is portable, applications are not.
And
that's why we also often see 'go and ask elsewhere' comments appearing here
[totally reasonable they are too of course].

Anyway, just a thought, and I wonder if anyone can come up with a counter to
it?

This is going to be a long(ish) story...

At my previous company, I've fought hard against people who think like
this. Our products run on a wide variety of different environment, all
with different OSes (some with none), all different CPU families and
all different compilers.

The products range from small 8bit PICs to medium 8bit Z80s to large
16bit 68000 to 486 all the way up to a modern 200Mhz ARM9. But they all
tend to have to do the same jobs - getting data over a serial line,
process and route the data and transmitting the data over serial lines
where necessary. Needless to say, this environment encouraged people to
keep re-inventing the wheel. And my bosses, engineers from the 70s,
thought this was the 'natural' way of doing things.

I believed in the portability of C and was appalled at this set-up.
Especially the re-inventing the wheel part. So I started writing
portable code for 'simple' stuff like CRC16 and base64 encoding etc.
using #ifdefs to select the appropriate implementations for resource
starved systems (PICs on average only have 20 bytes of ram). Then I
moved on to more complex stuff like a Modbus protocol engine.

Then the real struggle began - trying to convince people that this is
the way to go. I've already won converts among my team members since
they find it nice to be able to simply browse through my shared folder
of libraries to get what they needed. Slowly people started to
appreciate the effect of fixing a bug in a file fixes it for all
platforms.

The change in attitude towards writing code resulted in a huge library
of re-usable code. This allowed us to concentrate on adding new
features as well as freed us from being dependent on a single
CPU/platform. When our competitors shifted from 68000's to PPCs we were
able to do the same. When ARM became all the rage in embedded devices
we were able to move our product to it as well.

So, I've written code to work all the way from 4MHz, 8bit CPUs with 20
bytes of ram to 200MHz, 32bit CPUs with 128MB of ram and a hard disk.
The complete programs are obviously not portable since you can't expect
a 1MB program to fit on 1kB of EEPROM. But the code I've written, by
themselves, are portable. main() should ideally be the only
non-portable part of your code.
 
S

slebetman

pemo said:
Premise: any decently complex modern application cannot be entirely written
in standard C [meaning, the language without compiler added 'extensions',
and only using the standard libraries]. Or, if it is written in standard C,
then it is 'sub optimal' [and certainly doesn't have a nice UI!].

Well... yes since you often have to interact with the OS and
environment. But I don't re-write programs monolithically every time I
start a new project. I "drag&drop" libraries I've written over the
years and just write a new main file for the program.

Conclusion: Whilst the language is portable, applications are not.
And
that's why we also often see 'go and ask elsewhere' comments appearing here
[totally reasonable they are too of course].

Anyway, just a thought, and I wonder if anyone can come up with a counter to
it?

This is going to be a long(ish) story...

At my previous company, I've fought hard against people who think like
this. Our products run on a wide variety of different environment, all
with different OSes (some with none), all different CPU families and
all different compilers.

The products range from small 8bit PICs to medium 8bit Z80s to large
16bit 68000 to 486 all the way up to a modern 200Mhz ARM9. But they all
tend to have to do the same jobs - getting data over a serial line,
process and route the data and transmitting the data over serial lines
where necessary. Needless to say, this environment encouraged people to
keep re-inventing the wheel. And my bosses, engineers from the 70s,
thought this was the 'natural' way of doing things.

I believed in the portability of C and was appalled at this set-up.
Especially the re-inventing the wheel part. So I started writing
portable code for 'simple' stuff like CRC16 and base64 encoding etc.
using #ifdefs to select the appropriate implementations for resource
starved systems (PICs on average only have 20 bytes of ram). Then I
moved on to more complex stuff like a Modbus protocol engine.

Then the real struggle began - trying to convince people that this is
the way to go. I've already won converts among my team members since
they find it nice to be able to simply browse through my shared folder
of libraries to get what they needed. Slowly people started to
appreciate the effect of fixing a bug in a file fixes it for all
platforms.

The change in attitude towards writing code resulted in a huge library
of re-usable code. This allowed us to concentrate on adding new
features as well as freed us from being dependent on a single
CPU/platform. When our competitors shifted from 68000's to PPCs we were
able to do the same. When ARM became all the rage in embedded devices
we were able to move our product to it as well.

So, I've written code to work all the way from 4MHz, 8bit CPUs with 20
bytes of ram to 200MHz, 32bit CPUs with 128MB of ram and a hard disk.
The complete programs are obviously not portable since you can't expect
a 1MB program to fit on 1kB of EEPROM. But the code I've written, by
themselves, are portable. main() should ideally be the only
non-portable part of your code.
 
F

Flash Gordon

(e-mail address removed) wrote:

themselves, are portable. main() should ideally be the only
non-portable part of your code.

No, IMHO main should be portable, the non-portable bits should be in a
platform specific library.
 
E

Eric Sosman

pemo said:
Is C really portable? [...]

"Portable" is not a Boolean attribute. Worse, it's not
a one-dimensional attribute. Worst of all, its components
aren't all measurable.

"Portability" comes down to economy: How much time, money,
skull sweat, and caffeine will it take to get your program
working on a machine that hasn't hosted it before? Along with
the effort estimate goes another: How strong is the desire to
have the program work on some particular target system? It's
likely that your tic-tac-toe program would be difficult to get
running on your car's engine control computer, but the chances
that you'd want to do such a thing seem pretty remote.

"Portability" cannot even be assessed entirely from a
study of the code. For example, a program written to the
strictest coding standards and impeccably implemented might
still be "non-portable" to a system with less than 256MB of
memory. (The well-behaved program will, of course, fail
cleanly with a polite message -- but if the program cannot
carry out its intended function, it hasn't been "ported,"
has it?)

So: When we say that something is "portable" we're really
using a sort of shorthand for a whole big bag of imponderables.
"Non-portable" is similarly inexact. In c.l.c. usage, all of
these have been tagged as "non-portable;" I've tried to arrange
them in an approximate order from venial sins to deadly:

- Code that assumes two's complement integers

- Code that assumes a particular character encoding

- Code that assumes a particular endianness

- Code that assumes `int i; int j;' allocates the two
variables in adjacent memory locations

.... and, of course, many more. Clearly there are "portability
threats" of different kinds and magnitudes in such examples;
because c.l.c. is sort of rabid we tend to lose the differences
and tar them all with the same "non-portable" brush.

The really interesting thing, I think, is that it often
turns out that the restrictions on "portable" code are less
stringent than may appear at first. One reason I hang around
c.l.c. is that people keep coming up with more-portable ways
of doing things I'd been using less-portable code for; I usually
don't go back and retrofit my old code, but I say "Aha! Neat!"
and stash the technique in my toolbox for future use.
 
R

Roberto Waltman

pemo said:
Is C really portable? And, apologies, but this is possibly a little OT?
...snip...

Others have already given good replies. I would
like to add that "portability" depends more on
the developer's knowledge and goals than on a
particular programming language.

C programs can be portable, when written by
knowledgeable and experienced people with
the intention of making them portable.

When the intent, knowledge (1) or experience
are not there, portability will most likely
also be missing.

One of the best examples of portable code I
ever saw, was a set of cross-development
tools for 8080 processors. (Assembler,
linker & simulator.)
The programs were written in a subset of
Fortran, using only the features know to
be common across several Fortran dialects.
The character set encoding was "discovered"
at run time, translation tables were set
up so that the program could run unchanged
in machines using any character encoding:
ASCII, EIBIC, CDC (forget the name), etc.
Hollerith (character) strings were limited
to one character and arrays used for anything
else.
All the input/output functionality was
encapsulated in a couple of functions, so
any environment dependency that forced a
change here would not affect the rest of
the system.

These and similar techniques can be used in
any language to produce portable code.

-----------

(1) A colleague of mine came to me recently
telling he found a bug in GCC. A code segment
behaved differently in our target system,
(Linux on PPC + GCC) than in his test
environment (Windows + Visual C++).
A few questions revealed that he had just
discovered the amazing fact that the plain C
"char" data type can be signed or unsigned
depending on the implementation.
He has been programming in C & C++ for years,
and carries a business card with the title
"Senior Software Engineer".
I would not expect this gentleman to produce
any portable C code, even if his life depended
on that ...
 
S

slebetman

Flash said:
(e-mail address removed) wrote:



No, IMHO main should be portable, the non-portable bits should be in a
platform specific library.

That's only true if you want the whole program to be protable. As I've
described, that's not my case. The main must often do things that are
not 100% portable, like start threads, initialise libraries etc. For
what I'm doing, it's better to write portable libraries/functions and
be able to re-use them on any platform. Main tend to be very small
anyway, all it usually does is call other libraries, so it's not an
issue to re-write it. But that may not be how others write code, that's
just how I do it.
 
W

websnarf

pemo said:
Is C really portable?

No. The standard embodies a portable syntax which exists as subset of
any compliant compiler, but that's exactly as meaningless as you might
suspect it is. For example, I don't believe there exists any pair of C
compilers from different vendors that have exact source space
compatibility.
[...] And, apologies, but this is possibly a little OT?

Well C.L.C. is a group about ANSI standard C. I don't know why, but if
you wish to discuss the actual practice of programming in C you will
have to find some other newsgroup to post in.
In c.l.c we often see 'not portable' comments, but I wonder just how
portable C apps really are.

They're not. Amongst languages in common use today, C is just like
Visual Basic in that there just really isn't any real expectation of
portability on any real world application code. Nearly every other
language in common use today is far more portable than C.
I don't write portable C code [...]

(well practically nobody does so ...)
[...] - *not only* because, in a 'C sense', I
probably do things that aren't portable - but because for the last x years,
I've written code to run on a number of different platforms. Those apps
have had to make use of system calls, use threads, present nice UIs, .

Well, its not just that. The standard says integer overflow is
undefined, right shift is not deterministic, you can't assume 2s
complement math, you can't assume ASCII characters, you can't assume
IEEE 754 floating point, wide-characters are specifically specified
*not* to represent anything deterministic, no code can be considered
re-enterable, parameter computation order is not specified, etc.

Even avoiding system calls, user interfaces and threading, its still
very hard to write portable code in C.
Premise: any decently complex modern application cannot be entirely written
in standard C [meaning, the language without compiler added 'extensions',
and only using the standard libraries]. Or, if it is written in standard C,
then it is 'sub optimal' [and certainly doesn't have a nice UI!].

Yes, but this only addresses system and library function calls. Try
writing a reasonable performing crypto-library in pure C that is
completely portable.
Conclusion: Whilst the language is portable, applications are not.

A subset of the *syntax* is portable. Nothing more.
[...] And
that's why we also often see 'go and ask elsewhere' comments appearing here
[totally reasonable they are too of course].

Of course. This group is incorrectly named (or equivalently has been
taken over by people who have ideas for this group that don't
correspond to the name of it). It should be called comp.lang.c.ansi.
This group does not discuss the practice of C programming.

The exception, of course, is the tremendous leniancy given to people
asking questions about gcc, and giving answers that are specific to
gcc.
 
P

P.J. Plauger

No. The standard embodies a portable syntax which exists as subset of
any compliant compiler, but that's exactly as meaningless as you might
suspect it is. For example, I don't believe there exists any pair of C
compilers from different vendors that have exact source space
compatibility.

Probably true, but not terribly important. Having been in and
around the validation business for several decades, I can testify
that Standard C has way more implementations than any other
language; and many of them score nearly perfect on two or more
nontrivial validation suites. Put another way, I've sold C code
intended to be portable also for several decades and I've *never*
had to worry about whether that code will compile, and execute
correctly, on a multitude of platforms. (With C++, I *always*
worry.)

Before C came along, I was doing similar things with Fortran,
and with reasonable success. And I've used about half a dozen
other popular languages with lesser success. So, IM(extensive)E
C portability is far from meaningless to me. YM(obviously)V.
They're not. Amongst languages in common use today, C is just like
Visual Basic in that there just really isn't any real expectation of
portability on any real world application code. Nearly every other
language in common use today is far more portable than C.

Does your planet have an oxygen atomsphere? Just curious.
[...] And
that's why we also often see 'go and ask elsewhere' comments appearing
here
[totally reasonable they are too of course].

Of course. This group is incorrectly named (or equivalently has been
taken over by people who have ideas for this group that don't
correspond to the name of it). It should be called comp.lang.c.ansi.
This group does not discuss the practice of C programming.

The exception, of course, is the tremendous leniancy given to people
asking questions about gcc, and giving answers that are specific to
gcc.

If you weren't in such a sour mood, and if I weren't trying to
hold onto my recent good mood, I'd be tempted to agree with you,
at least to some extent.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
S

slebetman

pemo said:
Premise: any decently complex modern application cannot be entirely written
in standard C [meaning, the language without compiler added 'extensions',
and only using the standard libraries]. Or, if it is written in standard C,
then it is 'sub optimal' [and certainly doesn't have a nice UI!].

Conclusion: Whilst the language is portable, applications are not. And
that's why we also often see 'go and ask elsewhere' comments appearing here
[totally reasonable they are too of course].

Anyway, just a thought, and I wonder if anyone can come up with a counter to
it?

Well, even if the application can't be completely written in standard
C, it pays to be as close to portable as possible. Here's a list of
mostly portable, very non-trivial code in the real world where
portability is a major reason for their success:

1. Linux Kernel - now usually the first OS to be ported to a new CPU
2. BSD Kernel
3. Tcl interpreter - almost always the first scripting language to be
ported to a new OS or CPU
4. Tk GUI toolkit/library
5. gcc
6. Apache web server.
7. Adobe's postscript engine.

There are many others. Some assumes POSIX for portability. A few, like
the Tcl interpreter, don't even assume this. Tcl runs perfectly on a
386 in DOS.
 
W

websnarf

P.J. Plauger said:
Probably true, but not terribly important. Having been in and
around the validation business for several decades, I can testify
that Standard C has way more implementations than any other
language;

Thats nice, but not the question OP was asking. Please crack open a
dictionary: Availability != Portability.
[...] and many of them score nearly perfect on two or more
nontrivial validation suites. Put another way, I've sold C code
intended to be portable also for several decades and I've *never*
had to worry about whether that code will compile, and execute
correctly, on a multitude of platforms. (With C++, I *always*
worry.)

Before C came along, I was doing similar things with Fortran,
and with reasonable success.

Well yeah, and you could do the same thing with Visual Basic, and the
various Basic interpretors available for UNIXs, and so on. If you push
the entire job of portability up to the actual developer of the code,
well then in fact *MOST* languages are portable. If fact, did you know
its fact possible to be portable *BETWEEN* many languages? When you
put the onus onto the programmer, you can claim all sorts of
capabilities for your language.

There is a subtle difference between a language begin portable, and
software which has been painstakingly ported.
[...] And I've used about half a dozen
other popular languages with lesser success. So, IM(extensive)E
C portability is far from meaningless to me. YM(obviously)V.
They're not. Amongst languages in common use today, C is just like
Visual Basic in that there just really isn't any real expectation of
portability on any real world application code. Nearly every other
language in common use today is far more portable than C.

Does your planet have an oxygen atomsphere? Just curious.

Well my planet has Lua, Java, Python, Perl, TCL, and bizarre new
languages like Haskel, Scheme, etc. They are all portable.

Oh and BTW, my planet actually has mostly a Nitrogen atmosphere, though
it does includes a smaller proportion of oxygen, CO_2 and other
elements.
 
W

Walter Roberson

Well my planet has Lua, Java, Python, Perl, TCL, and bizarre new
languages like Haskel, Scheme, etc. They are all portable.

perl has horrible portability. Every time I want to do a non-trivial
perl update, whether it be a rev update or just bringing in a bunch
of new modules, it takes me pretty much a working day.

Indeed, I've been doing a module update today, and 22 of the modules
won't compile or won't test properly.

Last I checked, if you compile perl without threading then multiple
signals are not handled properly... and if you do compile with
threading then various other things break. :(
 
M

Mark McIntyre

They're not. Amongst languages in common use today, C is just like
Visual Basic in that there just really isn't any real expectation of
portability on any real world application code.

This is complete nonsense. Find me a Visual Basic compiler for Atari
ST, or Palm pilot, or IBM mainframe.
Nearly every other
language in common use today is far more portable than C.

You're fuller of sh*t than a midden.
Even avoiding system calls, user interfaces and threading, its still
very hard to write portable code in C.

and clueless.
 
M

Mark McIntyre

(of writing portable code)
Well yeah, and you could do the same thing with Visual Basic,

go on then, port some VB to Apple Mac, IBM Mainframe, Solaris, and Vax
11/780. And Blackberry.
Well my planet has Lua, Java, Python, Perl, TCL, and bizarre new
languages like Haskel, Scheme, etc. They are all portable.

Fascinating but not relevant to the question.
Oh and BTW, my planet actually has mostly a Nitrogen atmosphere, though
it does includes a smaller proportion of oxygen, CO_2 and other
elements.

Sounds habitable. One sun or two? I'm guessing one, but its possible
its two, apparently habitable planets can form round binary systems.

Can you send me the plans for your FTL transmitter by the way, its
very effective.
 
M

Malcolm

Eric Sosman said:
"Portability" cannot even be assessed entirely from a
study of the code. For example, a program written to the
strictest coding standards and impeccably implemented might
still be "non-portable" to a system with less than 256MB of
memory. (The well-behaved program will, of course, fail
cleanly with a polite message -- but if the program cannot
carry out its intended function, it hasn't been "ported,"
has it?)
Particularly when it could have produced the output, but slower, or less
accurately, or (here's the crucher) with less readable source code, on the
256MB machine.
"Non-portable" is similarly inexact. In c.l.c. usage, all of
these have been tagged as "non-portable;" I've tried to arrange
them in an approximate order from venial sins to deadly:

- Code that assumes two's complement integers

- Code that assumes a particular character encoding

- Code that assumes a particular endianness

- Code that assumes `int i; int j;' allocates the two
variables in adjacent memory locations

... and, of course, many more. Clearly there are "portability
threats" of different kinds and magnitudes in such examples;
because c.l.c. is sort of rabid we tend to lose the differences
and tar them all with the same "non-portable" brush.
"Good enough" portability is a huge problem.

For instance, if you are pasing an IFF file, most of the file is binary and
the clc regular will of course load in all the big-endian integers using a
big-endian read and the little-endian ones using a little-endian read.
Unfortunately the segment tags are ASCII, and it is very tempting to
hardcode 'A' 'I' 'F' 'F' (the tag for a sound file). This will work fine on
any ASCII system, and suddenly go wrong when the portable code is ported to
non-ASCII.
 
M

Malcolm

They're not. Amongst languages in common use today, C is just like
Visual Basic in that there just really isn't any real expectation of
portability on any real world application code. Nearly every other
language in common use today is far more portable than C.
C is probably the most portable for command-line type apps.
Nothing is very portable for GUIs. Java tries to be, but the original
library had to be abandoned because it didn't work. Also, lots of PCs don't
have Java Virtual Machines installed.

The exception, of course, is the tremendous leniancy given to people
asking questions about gcc, and giving answers that are specific to
gcc.
Unix people are morally superior to those who use and program Windows.
Didn't you realsie this?
 
W

websnarf

Walter said:
perl has horrible portability. Every time I want to do a non-trivial
perl update, whether it be a rev update or just bringing in a bunch
of new modules, it takes me pretty much a working day.

Indeed, I've been doing a module update today, and 22 of the modules
won't compile or won't test properly.

Last I checked, if you compile perl without threading then multiple
signals are not handled properly... and if you do compile with
threading then various other things break. :(

So you mean, its not easy to *INSTALL* right?
 
W

websnarf

Mark said:
This is complete nonsense. Find me a Visual Basic compiler for Atari
ST, or Palm pilot, or IBM mainframe.

Uhh ... no, they have *other* basic interpretors and compilers. I'm
sure they all can run the following:

10 PRINT "HELLO"
20 END

Which is the same situation as C.
 

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

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top