C, really portable?

N

Netocrat

There's already quite a lot thats conditional on the implementation
being able to support it, such as the entire IO library, the maths
library, and so on.

You mean on a non-hosted implementation, right?

| 5.1.2.2.2 Program execution
| In a hosted environment, a program may use all the functions, macros,
| type definitions, and objects described in the library clause (clause 7).
I can think of no reason to further bloat an
already massive document with a zillion pages entitled" this bit only
applies if you're using Zarniwhoot C 3.6 on a MicroBeeble 5 with Snork
2.4 or lower OS".

You have a good point re reducing bloat.

Afaics general classes of errors for printf isn't a badly flawed
suggestion, so long as they are optional for an implementation. jacob's
claim that this would aid portable error analysis seems to be correct.

Whether this is useful enough to counter an argument of bloat minimisation
is debatable, but introducing an example that misrepresents jacob by
suggesting he intended implementation-specific wording is an inflammatory
way to go about that debate.
 
M

Mark McIntyre

You mean on a non-hosted implementation, right?

indeed.
Afaics general classes of errors for printf isn't a badly flawed
suggestion, so long as they are optional for an implementation. jacob's
claim that this would aid portable error analysis seems to be correct.

Well, obviously I'm unconvinced, especially since there /are/ ways to
check this. I'd personally rather see the *printf functions set errno,
and leave it to implementations of perror etc to turn that into
something meaningful.
Whether this is useful enough to counter an argument of bloat minimisation
is debatable, but introducing an example that misrepresents jacob by
suggesting he intended implementation-specific wording

My problem is that /I/ think thats what he /has/ suggested.
is an inflammatory way to go about that debate.

Unfortunately his way of presenting his POV is so assertive that it
brings out the worst in many people.
 
M

Malcolm

Mark McIntyre said:
Only if the programmer is bad.
No.
A lazy programmer like me says

int main(void)
{
printf("Hello world\n"):
return 0;
}

and says that if stdout isn't working, there are probably all sorts of other
problems, so just let sys admin fix them.

A superior programmer says

int main(void)
{
int err;
err = printf("Hello world\n");
if(err < 0)
{
fprintf(stderr, "Stdout not working\n");
exit(EXIT_FAILURE);
}
return 0;
}

A super-duper top-notch programmer says

int main(void)
{
int err;
err = printf("Hello world\n");
if(err < 0)
{
printf_error_routine(err);
exit(EXIT_FAILURE);
}
return 0;
}

/*
printf_error_routine.c
Any program, this platform only.
*/

/*
default implentation - comment in if porting
void printf_error_routine(int ec)
{
fprintf(stderr, "printf failed with error code %d\n", ec);
}
*/

void printf_error_routine(int ec)
{
switch(ec)
{
case EOF:
fprintf(stderr, "Error on stdout\n");
break;
/* etc */
}
}

As the programmer gets better, the code gets more unreadable, less portable,
less maintainable, and more prone to bugs.
 
M

Malcolm

No, you said they were invalid:
Mark:
Yes, I realise thats what he was trying to trap. I don't consider a
string of length zero to be a valid string however. YMMV, as may
Paul's.
C convention, which Mark obviously didn't appreciate, is that the empty
string should be accepted by string functions.
However there was no implication that such strings are illegal -i.e.
impossible to produce in a correct C program.
 
M

Mark McIntyre

No, you said they were invalid:

which is not the same as illegal.

Perhaps you need to set your transporter to bring a copy of hte OED
over from Planet Earth so that when twisting other's words, you can be
twistier.

EOT.
 
P

P.J. Plauger

The problem there was that most compiler systems of the time did not
adhere to the standard, whether that standard was J & W, or the later ISO.
Borland and UCSD were notably non-compliant. However C had the great
advantage of more or less universal compliance with the C90 standard, or
the earlier drafts.

1) Fortran66 was widely honored by the early 1970s, but you still
needed Pfort to avoid the non-portabilities inherent in the language.
And you still were limited by the universe of discourse of a tool
for translating math formulas into assembly language.

2) UCSD failed to standardize byte order, and failed to advertise
the fact, so it missed the boat on having machine-independent
binaries and surprised novices all the time.

3) The limitations of Pascal I encountered stemmed from an inherent
lack of expressiveness in the language definition -- the portable
subset was just too weak. (Brian Kernighan wrote a now famous
essay on the subject after we completed Software Tools in Pascal.)

4) Borland, in fact, *saved* Pascal by turning it into a reasonably
powerful language. Too bad the Pascal Standard chose to rubber
stamp Wirth's test-tube implementation. But even Borland Pascal
is not as flexible a language as C.

5) I was writing, and selling, highly portable products in C long
before the C Standard was completed. And I was not alone.

6) C90 had more or less universal compliance from the get-go
because X3J11 attracted most of the dozens of C compiler
implementers. And we honored the past practices of the C
community way better than most other language committees.

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

Flash Gordon

That's pretty slithery ...


That would be pretty hard considering I've cited the dictionary
definition before as well.

http://www.sei.cmu.edu/str/indexes/glossary/portability.html
| Portability
| the ease with which a system or component can be transferred from
| one hardware or software environment to another [IEEE 90].

http://www.answers.com/main/ntquery;jsessionid=3tu9ngjnl23qn?tname=portable&method=6&sbid=lc04a
| por·ta·ble (pôr'tÉ™-bÉ™l, pÅr'-)
| adj.
| 3. Computer Science. Relating to or being software that can run on
| two or more kinds of computers or with two or more kinds of
| operating systems.

Tell me how you transfer to hardware (or a kind of computer) where the
language is not available and I'll accept that availability of the
language for targets is not part of portability.
And you've come to the conclusion that C is a portable language out of
that. Some might say there's something wrong with your worldview.

Some might say the world is flat, does that make it true?
I've been promulgating this "definition" for decades,

That's pretty sad ... Its like the swiftboat veterans who believe we
could have won in Vietnam if we had just stayed there.
[...] and I've repeatedly been told that it makes sense.

By who? Oh yes -- people in your worldview.

Well, people who disagree would hardly be telling him that he is
correct. I tend to agree with P.J. Plauger BTW.

No -- these are orthogonal concepts. The Hello world program is plenty
portable, but you wouldn't call it powerful. The fact that certain
platforms don't have C compilers, (affecting availability), doesn't
make the program itself non-portable.

It reduces the portability though, because it is a "hardware or software
environment" to which it cannot be transfered.
Similarly, you can look at the source code for Berkeley Db. Its
definately very powerful, and its got pretty reasonable availability,
and the high level API is very uniform -- but just take a look at the
source code! Its pathetic! Hand ported to each and every platform
one at a time, with only the very highest level of API portability!

The bulk of hte code is NOT CHANGED for each platform. As is generally
the case, they isolate the platform dependant areas of the code.
http://www.sleepycat.com/docs/ref/distrib/port.html
What does the mean? It means we *KNOW* it doesn't work on Itanium or
AMD64 platforms -- or at least we know it won't until it gets
painstakingly hand ported to those platforms. The upshot? BerkeleyDB
is inherently unportable, excepting for the fact that it has been
"ported by force" to a finite (though fairly large) number of
platforms.

The bulk of the code is very portable, it is only a relatively small
portion of the code that needs to be ported.
[...] C rates high on all these measures, making it IME the best candidate in many
cases for writing code intended to be portable.

Nonsense. For anything except the most trivial code, you put real
effort into porting C code,

Strange that I've ported real code that solved a complex problem with
absolutely no effort in the past. When I say no effort, I mean I copied
it on to a completely different system (a workstation instead of an
embedded DSP processor) wrote some test harnesses and debugged it on the
workstation. I then recompiled for the DSP and it worked with no further
changes, which was a great relief as I did not have decent debugging
tools for the DSP.
> and even when you do so, your best bet is
to stick with very conservative statements like "Its very portable, and
known to work on platforms X, Y, Z ..." when describing such
portability. The C specification covers non-2s complement, undefined
behavior on integer overflow, incorrect right shifting, etc but the
problem is that such platforms are barely available, so you can't test,
and so you can't be sure.

As has been stated, portability is not a boolean. In any case, I know
Java applications that won't run on SCO 5.0.4 running on a standard x86
based system. The same Java application will run on the same hardware if
you put a different OS on, specifically we have had customers upgrade to
SCO 5.0.7 to solve the problem without changing the HW. Java *is*
available for SCO 5.0.4, just not the right version. So even if you
write a Java application you don't know it will run on the specific OS
even if it runs on the specific HW.

Show me run-time generated code, autoserialized data structures or
coroutines in C.

I've got an interpreter written in standard C that allows me to run
run-time generated code within a C application. It does not let me do
everything, but it does allow one of the things you've asked for. I'm
sure many others have similar things.
Painful experience. If you can't right shift deterministically, you've

You can right shift deterministically if you use unsigned integer types.
lost performance. If you can't assume integer size, you've lost

Use the int_least types and mask down (or if using C89 a type guaranteed
to be large enough), any decent compiler will eliminate the mask if the
type was the exact size required.
performance. Standard cryptographic algorithms require exact scalar
integer size knowledge (have "at least" such and such many bits is not
helpful -- it needs to be exact), deterministic right shifting,

See comments above.
> no
integer overflow,

Use unsigned integer types and that's done, assuming you want the result
to wrap (which I think you do) rather than limiting (which some
processors can do).
> and double-wide integer multiply.

You cast to a large enough unsigned integer type, unless you are going
beyond the largest integer type guaranteed to be available. Since you've
not said how large a "double-wide" is we can't tell.
> If you are forced
to emulate those operations (which the ANSI C standard requires, if you
are writing such code), your performance drops.

See comments above. Mainly use unsigned types.
[...] And who the hell are you to tell
me what matters to me or what has meaning to me? Get stuffed.

If you try to implement high performance code, especially crypto, with
just standard C how do you expect to do so with "remarkably low
effort"? You'll end up giving up on one of those things.

You think using an interpreted language does not have an impact on
performance? Or a language that forces the compiler to jump through
various hoops to implement the semantics you've decided on?
You see, a lot of people are using google to read usenet now. It means
people can literally check your statements with the click of the mouse.
You can't rely on the news servers expiring your articles in hopes
that nobody will check what you say. In posts leading up to this one,
you've mentioned Fortran and Pascal -- this is in a response to my
statements about "modern languages in common use".

Well, I've mentioned Java.
[...] If you take too much pain in porting the code,
somewhere along the line the cost of a complete rewrite
proves to be lower and the code is "not portable". (You
sometimes find that out too late.)
Now tell me who's being black and white?
If the cost is $17,000, that's a "degree".

No, that's a *MEASURE*. Measures, like cost, can go to infinity (in
theory). Degrees, as it is meant here, basically is between 0% and
100% (between 0 and 360 if you are talking about a circle, but its the
same idea). Do you see the difference?

I've dealt with hardware that had a movement range of greater than 360
degrees. In any case, you can scale cost in to a 0% to 100% range using
a non-linear scale such that 0% portable is infinite cost and 100% is 0
cost if that is what you want.
Ok, but you miss my point. Why is it ok for *you* to synthesize an
arbitrary black and white,

He did not. He just showed the difference.
> but when I just cite a commonly accepted
black and white (source code being portable or not), you get to deride
me for it?

I don't know of anyone other than you that considers portability to be a
black or white issue.
But the problems, in the case, *came* from C, the language it was
implemented in. Once its up and running, presumably, he'll have the
portable Perl language ready for him to use.

Apart from the fact that it was stated that once you have perl up and
running not all programs written in pure perl will actually run on it
for the simple reason that not all features that are part of perl on one
target are part of perl on another target, and perl is defined as being
that which is implemented as perl on the specific target of interest.
 
E

Eric Sosman

Keith said:
Eric Sosman said:
jacob navia wrote:
[...]
The result of printf is negative if there was an error,
but the exact values are implementation specific and
will change from this implementation of printf to the
next one. This makes impossible any error analysis
of that function call in a portable way.

Nonsense. <stdio.h> defines a macro named EOF, and
the expansion of that macro is the negative value you
mention. You can portably compare `r' to EOF and make
decisions based on equality or inequality. In this case
you can even forego EOF altogether and just test `r<0'
to see whether an error has occurred.


No, the standard says:

The fprintf function returns the number of characters transmitted,
or a negative value if an output or encoding error occurred.

There's no implication that the negative value is the same as EOF.

You're right; my error. (Portably detected ;-) The
`r<0' test still works just fine, though.
 
P

P.J. Plauger

That's pretty slithery ...

No, it's an honest statement. The fact is that the meaning of
words comes out of popular usage. (See the OED.) If a dictionary
definition is demonstrably incorrect or incomplete, it behooves
you to clarify what is actually meant in common parlance. You
can't think or communicate clearly until you have a sharp,
shared meaning for the words you use to describe critical concepts.
That would be pretty hard considering I've cited the dictionary
definition before as well.

Okay, you asked for it. I'll deal with the rest of your posting
separately (if the mood strikes me). Let's look at your self
proclaimed integrity vis a vis dictionary definitions.

I chased your links:

http://www.m-w.com/dictionary/portable
http://www.thefreedictionary.com/portable
http://dictionary.reference.com/search?q=portable

and found two distinct definitions of "portable" related to
computing:

Merriam-Webster:

1b: usable on many computers without modification <portable software>

American Heritage Dictionary:

3: Computer Science. Relating to or being software that can run on
two or more kinds of computers or with two or more kinds of operating
systems.

So it's clear that the dictionary definitions confine themselves
to *software*. Thus, the OP's elliptical question, "C, really
portable?" is nonsense. C is not software, but a programming
language. Nevertheless, you initially joined in the nonsense:

: pemo wrote:
: > 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.

So you begin by applying your beloved definition(s) to something
they were never intended to cover. And you go on in that vein
for several paragraphs.

Then the subject matter shifts:

: > I don't write portable C code [...]
:
: (well practically nobody does so ...)

You're now discussing portability in the dictionary sense,
but you're uttering demonstrable nonsense. In a *practical*
sense, *quite a few* people write portable code. Just look
around you.

After a few more paragraphs on this theme, the discussion
shifts again:

: > Conclusion: Whilst the language is portable, applications are not.
:
: A subset of the *syntax* is portable. Nothing more.

Now you're applying the concept of portability to syntax.
Nothing about that in any of your dictionaries, so once
again you're talking nonsense, but of a different flavor.

Then, in your first reply to me you said:

: > 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.

Now, portability is a "job" for the programmer. Or wait,
it's back to being an attribute of a language. No, it's
a thing that can exist *BETWEEN* (emphasis yours) many
languages. The dictionaries are receding at the speed of
light.

But we're not done yet. In the next paragraph, you say:

: There is a subtle difference between a language begin portable, and
: software which has been painstakingly ported.

Now we see yet another concept -- "porting" is something that's
*done* to programs. Not in your dictionaries, which insist that
portability comes "without modification". No pains there.

Then, a few posts later, we find you saying:

: Portability describes a *CHARACTERISTIC* of the degree of
: transportability of source code. By itself, its not a measure of cost.

Now you're talking about a "degree of transportability",
but neither of your beloved dictionary definitions treats
"portable" as anything other than a Boolean attribute.

And then:

: > [...] it's not a Boolean. Availability is thus an important
: factor in improving portability.
:
: No. Availability affects where you can port to. The nature of a given
: source code's portability is always taken against the set of platforms
: that have a compiler for that platform.

Now code is portable only if there's a compiler for a given
platform. Where does it say that in any dictionary?
(It's also not necessarily true.)

And then we come to:

: > Only if you think in black and white. We informally say that
: > a language is portable if it lowers the cost of writing
: > programs that are portable (cheaper to move than to completely
: > rewrite).
:
: Well no, *you* informally say that, because you have little respect for
: precise language. Its a good thing you aren't on any committee that
: manages a international standard. Oh wait ...

First you deny that you're using portability in a popular,
but non-dictionary sense, when you clearly are. Then you
accuse *me* of being imprecise, even though I was careful
to say what I meant and you were, shall we say, haphazard
at best. Then you fall back on insults, the last refuge of
the rhetorically challenged.

But then you say:

: http://www.m-w.com/dictionary/portable
: http://www.thefreedictionary.com/portable
: http://dictionary.reference.com/search?q=portable
:
: There's nothing about cost in any of those definitions. Also notice
: that the definitions include the "two or more platforms" in them.
: Meaning that "portability" is not related to the number of platforms
: your code is portable, but rather the degree to which the software
: itself is inherently portable.

After brushing up on the definitions, you immediately say
portability is not related to the number of platforms
your code is portable, which directly contradicts the
previous sentence. And then you introduce the concept
of "degree of inherent portability" which is *not* in
the dictionary and *not* precisely any of the things
you said earlier.

So please don't lecture me on the proper use of dictionaries,
or precision in communication. And watch who you're calling
slithery. If the snake skin fits...

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

Emmanuel Delahaye

jacob navia a écrit :
Is a program just using printf portable?
For instance this one:

#include <stdio.h>
int main(void)
{
int r=printf("hello world\n");
}

Is not portable.

It is.
Why?

The result of printf is negative if there was an error,

So what ? You don't even read r in your code.

What about

if (r < 0)
{
perror ("stdout);"
}

Sounds very portable to me.
 
E

Emmanuel Delahaye

jacob navia a écrit :
This is just polemic. My message was clear: the error analysis of
a printf call is not portable.

printf ("%07L\n",23.78);

how do I detect the format error in my program without
tying me to a specific printf implementation???

Maybe you should try a better compiler :

Compiling: main.c
main.c: In function `main_':
main.c:10: warning: unknown conversion type character 0xa in format
main.c:10: warning: too many arguments for format
 
E

Eric Sosman

Mark said:
And how could such error analysis be portable?




Lets go on: Which sort of IO error? What caused it? Who was running
the programme at the time? How much memory was in use? How many
diskdrives were busy? Which horse running in the 3:30 at Kempton? You
see my point?

Aha! So THAT's what's bothering you? You want a
distinct, documented code for every detectable error
condition?

Try the exercise of composing a list of all possible I/O
error conditions. If you make an honest attempt, I'm sure
you'll find the list unmanageably long. If you don't find
it so and have the intestinal fortitude to post your complete
list, I'm equally sure there will be no shortage of people
ready to pounce and point out error conditions you omitted.
Consider, too, that new I/O devices with new failure modes
are being invented all the time: the list will not remain
static.

The only way to keep the list to a manageable length is
to group multiple error conditions together -- and as soon
as you do so, of course, you're suppressing information
about the "root cause" error. You keep mentioning a "disk
full" error -- but is that really the root cause? No, the
disk actually has plenty of room but your account has reached
its quota. Even that isn't the ultimate cause, because the
I/O system automatically contacted the billing system to see
if it could purchase some more quota for you on the fly, and
the ultimate I/O error is "Credit card rejected."

Should the C Standard document a special printf() return
value for "Credit card rejected?"

Withdrawing from the verge of the ridiculous (but only
from the verge; think of buzz-phrases like "grid computing"),
let's get back to what your program would DO with this rich
source of information. As things stand today, all you learn
is that the printf() operation failed. If you're checking for
the failure (which you should, if your program is a "filter"
or other such utility), what would your program do differently
if it could distinguish "disk full" from "SCSI bus failure"
from "NFS server not responding?" You're imagining, it seems,
something like

int r = printf("hello, world\n");
if (r < 0) {
switch (r) {
case IOERR_DISK_FULL: ...; break;
case IOERR_OVER_QUOTA: ...; break;
case IOERR_NETWORK_FAILED: ...; break;
case IOERR_DISK_FAILED: ...; break;
/* etc. */
}

What, exactly, would replace each set of ellipses, and how
would your handling of IOERR_BAD_MEMORY_PARITY differ from
IOERR_BLACKBERRY_LOST_PATENT_FIGHT_AND_TERMINATED_SERVICE?

If you want to write hardware diagnostics in C, you can
(probably, and with suitable extensions) do it. But it's a
little extreme to require the ability to do so "portably."
 
J

jacob navia

Hi Eric

I am not saying that the standard should specify
all possible errors. I am only saying that certain RANGES
of error codes should be specified so that portable programs
could test for i/o errors. This is all the more evident in
fprintf:
r = fprintf(...);
if (r >= MIN_PRINTF_IOERROR && r < MAX_PRINTF_IOERROR ) {
// Error handling for i/o errors
}

That would be portable now you see?

if (r >= MIN_PRINTF_FORMAT_ERROR && r < MAX_PRINTF_FORMAT_ERROR)
// handle printf format errors

What do you DO now to test for fprintf errors?

Well, you have to code:
r = fprintf(....);
#ifdef LINUX
#ifdef TRIO_PRINTF
if (r == ...)
#elif GCC_PRINTF
if (r ==...)
#elif defined(WINDOWS)
#ifdef LCC_WIN32
if (r == ...)
#elif defined(WATCOM)
#elif defined (GCC)

#endif

etc etc, ad nauseum!

The standard would define a RANGE of values dedicated to specific errors
so that the calling program could determine what type of failure
happened, INDEPENDENTLY from the specific printf implementation.
 
P

P.J. Plauger

Now, where was I? I'll skip a few slurs and pick up with:
And so, if your brother were trying to port C code that was
multithreaded and had GUI calls, do you think your brother would have
an easier time?

Yep. He's done that too, for a couple of decades.
Your point here seems really irrelevant. Its true
that race conditions are not portable and that Java has been going
through growing pains, but I seem to remember a time when C was hardly
in better shape ("far" and "near" anyone?) The main difference being
that Java appears to have long ago solved problems that C never has.

Wait, is Java a modern language superior to C, or is it still
going through growing pains? The fact is, Java hit the deck
promising that even novices could write multithreaded code
that was safe and portable; after several revisions of the
underlying model, that's still not true. A popular dialect of
C (never standardized) used far and near pointers, to good
effect, to deal with a practical architectural issue. (They
even proved useful on a couple of non-X86 platforms as well.)
Whatever problems they caused pale compared to the races,
deadlocks, and sheer lack of portability inherent in Java
threading.

Java indeed "solved" a number of problems that C never has,
like flexible types and arithmetic representations. C hasn't
solved them because some of understand that they're not
problems.
No -- these are orthogonal concepts. The Hello world program is plenty
portable, but you wouldn't call it powerful.

Right. What I said was that portability has several components,
which I agree are orthogonal. I did *not* say that all portable
programs are powerful. You need to bone up on syllogisms.
The fact that certain
platforms don't have C compilers, (affecting availability), doesn't
make the program itself non-portable.

Right. What I said was that portability is not a Boolean, but a
quantity (cost, degree, whatever) measurable along several axes.
You've got your contrast knob turned up again (and your syllogizer
turned down, apparently).
Similarly, you can look at the source code for Berkeley Db. Its
definately very powerful, and its got pretty reasonable availability,
and the high level API is very uniform -- but just take a look at the
source code! Its pathetic!

Once again, power is not the only measure of portability,
or a synonym for it. Perhaps you should go back to Venn
diagrams and come forward once more.
[...] C rates high on all these measures, making it IME the best
candidate in many
cases for writing code intended to be portable.

Nonsense. For anything except the most trivial code, you put real
effort into porting C code, and even when you do so, your best bet is
to stick with very conservative statements like "Its very portable, and
known to work on platforms X, Y, Z ..." when describing such
portability.

Right. And that's exactly what you do with *every* program
that purports to be portable in the real world. Try telling
a project manager, "Don't bother to test the Java (or Perl,
or whatever) components before shipping -- they're guaranteed
to work on all supported platforms." Uh huh.

I agree that writing portable code takes effort, which is
why I often advise people not to aim for portability unless
they're really sure they'll actually do one or more ports.
Otherwise, you'll never recoup the investment. I simply
observe that when I do choose to invest in portable C code,
the extra cost is not that great for the reward in extra
usability/marketability.
The C specification covers non-2s complement, undefined
behavior on integer overflow, incorrect right shifting, etc but the
problem is that such platforms are barely available, so you can't test,
and so you can't be sure.

Well, actually I've long since learned to avoid all those
gray areas you cite. We also tell our customers where we've
tested and where we haven't. We also develop test suites
for all our products, so a customer who wants to move our
stuff to a new platform faces a lower potential cost. And
we do exactly the same for our non-C products.
No, I mean things like ftp servers (its in the built-in libraries in
Python),

Probably written in C, and callable from C. So you think a
programming language has to ship with a huge library to call
itself portable? I don't.
consistent numerics,

Having written numeric programs in multiple languages for over four
decades, I can assure you that the vast majority of portability
problems in that arena have next to nothing to do with the
consistency of numeric properties. A foolish consistency is,
in fact, a hindrance. (Think of Java and its pro-Sparc, anti
Pentium "consistent numerics".)

run-time generated code,

You mean like templates? Or generics? Or plain old macros?
auto-serialized
data structures, threading, built-in array/string safety and memory
leak protection and so on.

All of those are nice, and all of them are available in most of
the C compilers I use. Requiring them to be in the standard
library shipped with a language translator is, however, a
two-edged sword.
[...] I write Maplesoft scripts to do things in minutes that
would be impractical in C. But if by powerful you mean that there
are few limitations on what you can manage, then C wins hands down.

Show me run-time generated code, autoserialized data structures or
coroutines in C.

And I've done all those things in C. When I have a problem that
needs one of those features, I'll often write the necessary piece
in a more suitable language (one that knows how to call all those
C functions already written for its runtime library). But sometimes
it's worth writing in C. And almost always the low-level magic
code and the glue code *has* to be written in C. I don't write
device drivers in Maplesoft.
Painful experience. If you can't right shift deterministically, you've
lost performance. If you can't assume integer size, you've lost
performance. Standard cryptographic algorithms require exact scalar
integer size knowledge (have "at least" such and such many bits is not
helpful -- it needs to be exact), deterministic right shifting, no
integer overflow, and double-wide integer multiply. If you are forced
to emulate those operations (which the ANSI C standard requires, if you
are writing such code), your performance drops.

Excuse me, but you made two statements about things that go on
inside my head. And you happen to be wrong. You're defending them
by stating opinions that come from inside *your* head. And I
happen to believe most of those opinions are not supported in
the real world. I am undisputably the world's foremost authority
on what goes on inside my head. You seem to have problems
distinguishing my reality from your personal reality from the
real world we both inhabit. I try not to.
[...] And who the hell are you to tell
me what matters to me or what has meaning to me? Get stuffed.

If you try to implement high performance code, especially crypto, with
just standard C how do you expect to do so with "remarkably low
effort"? You'll end up giving up on one of those things.

Even after my intentional vulgarism, you fail to note that
your presumptuous behavior is insulting. We are *not*
discussing whose view of the real world is superior. We're
talking about your inability to distinguish realities.
That's an awfully early developmental stage to get stuck at.
You see, a lot of people are using google to read usenet now. It means
people can literally check your statements with the click of the mouse.
You can't rely on the news servers expiring your articles in hopes
that nobody will check what you say.

Why do you think I do? I have a long track record of standing
by what I say, and acknowledging errors when I (too often)
commit them.
In posts leading up to this one,
you've mentioned Fortran and Pascal -- this is in a response to my
statements about "modern languages in common use".

Right. But that's not the *only* thing I've said, by a
long shot. Your syllogisms are once again bass-ackwards.
[...] If you take too much pain in porting the code,
somewhere along the line the cost of a complete rewrite
proves to be lower and the code is "not portable". (You
sometimes find that out too late.)

Now tell me who's being black and white?

If the cost is $17,000, that's a "degree".

No, that's a *MEASURE*. Measures, like cost, can go to infinity (in
theory). Degrees, as it is meant here, basically is between 0% and
100% (between 0 and 360 if you are talking about a circle, but its the
same idea). Do you see the difference?

Now that you say "as is meant here" I see the difference *to you*.
But I'm not privy to what's inside your head. (That separation
thing again.) I tried your first dictionary link and found
your preferred definition seventh on the list. Several of the
earlier ones were consistent with my usage. Nyah.
Ok, but you miss my point. Why is it ok for *you* to synthesize an
arbitrary black and white, but when I just cite a commonly accepted
black and white (source code being portable or not), you get to deride
me for it?

Sigh. What I said was that you make a Boolean out of a quantity
by using it in a comparison predicate. I used that as an
example of how people can conclude that a program is "not
portable" by performing some sort of implicit or explicit
quantitative estimate. The point is that portability
becomes a Boolean *only* when you apply a predicate to it.
But the problems, in the case, *came* from C, the language it was
implemented in. Once its up and running, presumably, he'll have the
portable Perl language ready for him to use.

Other people have challenged your presumption better than I can.

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

Kleuskes & Moos

jacob navia a écrit :

It is.

So what ? You don't even read r in your code.

What about

if (r < 0)
{
perror ("stdout);"
}

Sounds very portable to me.

<nitpick>
Highly portable. It should produce an error in every conforming compiler.

ITYM

if (r < 0)
{
perror ("stdout");
}
</itpick>
 
R

Richard Heathfield

Malcolm said:

Authors of C textbooks are valauble people on the ng, and shouldn't be
insulted, wouldn't you agree?

Not necessarily - imagine Schildt becoming a clc regular! But if you think I
was complaining at Mr Plauger's reaction to Hsieh's insulting behaviour,
think again. It was in fact rather more low-key and restrained than Hsieh
deserved.

No, I just thought that, from such an eminent source, this would make an
excellent quote for people who like collecting them. It is a quote that
will mature with the years, as the context fades from memory.
 
R

Richard Heathfield

Malcolm said:
A lazy programmer like me says

int main(void)
{
printf("Hello world\n"):
return 0;
}

Undefined behaviour.
A superior programmer says

int main(void)
{
int err;
err = printf("Hello world\n");
if(err < 0)
{
fprintf(stderr, "Stdout not working\n");
exit(EXIT_FAILURE);
}
return 0;
}

Requires a diagnostic message at translation time.

A super-duper top-notch programmer says

int main(void)
{
int err;
err = printf("Hello world\n");
if(err < 0)
{
printf_error_routine(err);
exit(EXIT_FAILURE);
}
return 0;
}

Requires a diagnostic message at compile time.

As the programmer gets better, the code gets more unreadable, less
portable, less maintainable, and more prone to bugs.

I didn't notice any particular evidence of a good programmer at work in the
code you posted.
 
E

Eric Sosman

jacob said:
Hi Eric

I am not saying that the standard should specify
all possible errors. I am only saying that certain RANGES
of error codes should be specified so that portable programs
could test for i/o errors. This is all the more evident in
fprintf:
r = fprintf(...);
if (r >= MIN_PRINTF_IOERROR && r < MAX_PRINTF_IOERROR ) {
// Error handling for i/o errors
}

That would be portable now you see?

if (r >= MIN_PRINTF_FORMAT_ERROR && r < MAX_PRINTF_FORMAT_ERROR)
// handle printf format errors

The "handling" of a format error is, presumably, to
announce that a programming bug has been encountered. Note
that some "format errors" (I'm guessing a little bit about
what you mean) aren't detectable at run-time anyhow, not
without expensive extra machinery like explicit type codes
attached to all the variable arguments. "Format errors" like

char not_a_string[13] = "hello, world!";
printf (not_a_string);

are only detectable at extreme expense.
What do you DO now to test for fprintf errors?

Well, you have to code:
r = fprintf(....);
#ifdef LINUX
#ifdef TRIO_PRINTF
if (r == ...)
#elif GCC_PRINTF
if (r ==...)
#elif defined(WINDOWS)
#ifdef LCC_WIN32
if (r == ...)
#elif defined(WATCOM)
#elif defined (GCC)

#endif

etc etc, ad nauseum!

No; I just write

f = fprintf(....);
if (r < 0) {
perror ("fprintf"); /* debatable */
...
}

The perror() call is dubious because the Standard doesn't
require that fprintf() set errno to anything meaningful. Some
people feel that calling perror() in such a case is a Bad Thing
because the message "fprintf: incorrect password" resulting from
a bogus errno value might be confusing. I take the optimistic
view that "fprintf: disk full" might be helpful, and am willing
to risk being misled once in a great while. This is, if you like,
a non-portable aspect of C's error reporting -- but it's venial,
and doesn't justify your "reasonable usage [...] is impossible."
The standard would define a RANGE of values dedicated to specific errors
so that the calling program could determine what type of failure
happened, INDEPENDENTLY from the specific printf implementation.

This would require that the Standard enumerate all
categories of errors -- maybe not every single possible
error, but at least all categories. Categorization involves
simplification: By lumping umpty-mumble errors into a single
category, you lose those errors' individual identities. Now,
you're evidently discontented with the ultimate simplification
and identity loss of "An error occurred," and would prefer to
discriminate more finely. Do you imagine that the level of
detail that satisfies you would satisfy everyone else?

Setting aside ranges rather than individual values solves
anything. You are (apparently) happy to lump all "I/O errors"
together, so long as they're distinct from "format errors."
Someone else might want to distinguish "logical I/O errors"
(disk full, security violation, ...) from "physical I/O errors"
(SCSI bus reset, modem hangup, ...), and this would require
subdividing your {MIN,MAX}_PRINTF_IOERROR range. And the next
guy would want to separate "real hardware errors" from "network
errors," and subdivide the subdivided ranges ... When you arrive
at the point where each range contains just one element, you're
back to enumerating every error again.
 
P

P.J. Plauger

Malcolm said:




Not necessarily - imagine Schildt becoming a clc regular! But if you think
I
was complaining at Mr Plauger's reaction to Hsieh's insulting behaviour,
think again. It was in fact rather more low-key and restrained than Hsieh
deserved.

No, I just thought that, from such an eminent source, this would make an
excellent quote for people who like collecting them. It is a quote that
will mature with the years, as the context fades from memory.

Aw, shucks. And I was just trying to be rude.

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

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
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top