Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

The illusion of "portability"

5 views
Skip to first unread message

jacob navia

unread,
Jul 31, 2006, 5:30:45 PM7/31/06
to
In this group there is a bunch of people that call themselves 'regulars'
that insist in something called "portability".

Portability for them means the least common denominator.

Write your code so that it will compile in all old and broken
compilers, preferably in such a fashion that it can be moved with no
effort from the embedded system in the coffe machine to the 64 bit
processor in your desktop.

Sure, you can do that. But as you know, there is no free lunch.
You pay for that "portability" by missing all the progress done
since 1989 in C.

Note that there is objectively speaking not a single useful
program in C that can be ported to all machines that run the
language.

Not even the classic

int main(void) { printf("hello\n");}

Why?

For instance, if we take that program above and we want to
know if our printf did write something to stdout, we have to write


int main(void) {
int r=printf("hello\n");
if (r < 0) {
// what do we do here ???
}
}

The error code returned by printf is nowhere specified. There is no
portable way for this program to know what happened.

Since printf returns a negative value for an i/o error OR for a
format error in the format string there is no portable way to
discriminate between those two possibilitiess either.

Obviously, network i/o, GUIs, threads, and many other stuff essential
for modern programming is completely beyond the scope of "standard C"
and any usage makes instantly your program non portable.

This means that effectively 100% of real C software is not portable to
all machines and that "portability" is at best a goal to keep in
mind by trying to build abstraction layers, but no more.

This is taken to ridiculous heights with the polemic against C99, by
some of those same 'regulars'.

They first start yelling about "Standard C", and then... they do not
mean standard C but some other obsolete standard. All that, in the name
of "portability".

Who cares about portability if the cost is higher than "usability"
and easy of programming?


jacob

Richard Heathfield

unread,
Jul 31, 2006, 5:50:33 PM7/31/06
to
jacob navia said:

> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".

The term "regulars" is a common one to describe those who frequent a forum,
whether it be an IRC channel, a newsgroup, or whatever. You yourself are a
"regular" in comp.lang.c, whether you realise it or not.

> Portability for them means the least common denominator.

Wouldn't it be better to ask "them" (whoever "they" are) what they mean by
portability, than to assume it? It is quite likely that the word is used in
slightly different ways by various people; it's not a very portable word.

<snip>

> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.

There isn't all that much progress in C. What did C99 give us? Mixed
declarations? Sugar. // comments? More sugar. VLAs? More sugar. Compound
literals - sure, they might come in handy one day. A colossal math library?
Hardly anyone needs it, and those who do are probably using something like
Matlab anyway.

The real progress has been in the development of third-party libraries, many
of which are at least a bit cross-platform.

> Note that there is objectively speaking not a single useful
> program in C that can be ported to all machines that run the
> language.

So what should I do with all mine? Delete them? Dream on.

> Not even the classic
>
> int main(void) { printf("hello\n");}
>
> Why?

Because the behaviour is undefined. Sheesh.

> Obviously, network i/o, GUIs, threads, and many other stuff essential
> for modern programming is completely beyond the scope of "standard C"
> and any usage makes instantly your program non portable.

Well, it certainly makes your program /less/ portable. I use wrappers around
sockets so that I at least have portability across the Win32/Linux divide.

> This means that effectively 100% of real C software is not portable to
> all machines and that "portability" is at best a goal to keep in
> mind by trying to build abstraction layers, but no more.

Portability is itself an abstraction, and a rather fuzzy one at that. There
is a lot of grey in between "portable" and "non-portable".

> This is taken to ridiculous heights with the polemic against C99, by
> some of those same 'regulars'.

There isn't any polemic against C99. You have misunderstood. The position of
at least some of the clc regs is that C99 will be just fine - when it
arrives. But it hasn't yet arrived in sufficient volumes to make the switch
from C90 worthwhile.

> They first start yelling about "Standard C", and then... they do not
> mean standard C but some other obsolete standard. All that, in the name
> of "portability".

Well, I'd rather conform to an obsolete standard that is supported by just
about all current C compilers, rather than to a standard that is not.

> Who cares about portability if the cost is higher than "usability"
> and easy of programming?

It's a trade-off, obviously. Some people will value portability more than
others. Those who don't value it very highly will wander off to newsgroups
dealing with their compiler, OS, or whatever. Those who do value it highly
tend to stick around here. Those who value it highly but who must also use
implementation-specific tricks on occasion can get the best of both worlds
- high quality platform-independent advice here, and platform-specific
advice in a platform-specific group. Sounds sensible to me.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Frederick Gotham

unread,
Jul 31, 2006, 5:59:31 PM7/31/06
to
jacob navia posted:

> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".


Agreed.


> Portability for them means the least common denominator.


"Portability" means "code which must compile successfully with every
compiler, and behave appropriately on all platforms".


> Write your code so that it will compile in all old and broken
> compilers, preferably in such a fashion that it can be moved with no
> effort from the embedded system in the coffe machine to the 64 bit
> processor in your desktop.


I'd aim for such.


> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.


Present(verb) arguments in support of this statement -- I would like to
debate this with you.


> Note that there is objectively speaking not a single useful
> program in C that can be ported to all machines that run the
> language.


If you're talking about GUI programs, then perhaps yes.

But the actual core algorithmic code can be kept fully portable. I've
written programs where all the core code is fully portable.


> Not even the classic
>
> int main(void) { printf("hello\n");}
>
> Why?
>
> For instance, if we take that program above and we want to
> know if our printf did write something to stdout, we have to write
>
>
> int main(void) {
> int r=printf("hello\n");
> if (r < 0) {
> // what do we do here ???
> }
> }
>
> The error code returned by printf is nowhere specified. There is no
> portable way for this program to know what happened.


Nor would I care what happened. If a system can't reliably print a few
miserable characters to the screen, then I wouldn't waste electricity by
plugging it in.


> Since printf returns a negative value for an i/o error OR for a
> format error in the format string there is no portable way to
> discriminate between those two possibilitiess either.


It's the programmer's responsibility to ensure that the format string isn't
corrupt. (Nonetheless, my own compiler warns of such an error.)


> Obviously, network i/o, GUIs, threads, and many other stuff essential
> for modern programming is completely beyond the scope of "standard C"
> and any usage makes instantly your program non portable.


Only the part of the program which deals with GUI, threads, etc.

The underlying algorithms can be (and should be where possible) fully
portable.


> This means that effectively 100% of real C software is not portable to
> all machines and that "portability" is at best a goal to keep in
> mind by trying to build abstraction layers, but no more.


Again, you're only talking about system calls.

Many times, I have written a program in fully portable code (in C++
albeit), and then progressed to write a platform-specific interface.

The core of my code remains fully portable.

Lately, I've begun to use GUI packages which one can use to compile
programs for systems such as Windows, Linux, Mac OS.

--

Frederick Gotham

jacob navia

unread,
Jul 31, 2006, 6:16:50 PM7/31/06
to
Richard Heathfield a écrit :

> There isn't all that much progress in C. What did C99 give us?

True, C99 didn't really advance the language that much, but it has some
good points. Anyway, if we are going to stick to standard C, let's agree
that standard C is Standard C as defined by the standards comitee.

> Mixed declarations? Sugar.
// comments? More sugar. VLAs? More sugar.

And what do you have against sugar?
You drink your coffee without it?

I mean, C is just syntatic sugar for assembly language. Why
not program in assembly then?

Mixed declarations are a progress in the sense that they put the
declaration nearer the usage of the variable, what makes reading
the code much easier, specially in big functions.

True, big functions are surely not a bright idea, but they happen :-)

I accept that this is not a revolution, or a really big progress in C
but it is a small step, what is not bad.

VLAs are a more substantial step since it allows to allocate precisely
the memory the program needs without having to over-allocate or risk
under allocating arrays.

Under C89 you have to either:
1) allocate memory with malloc
2) Decide a maximum size and declare a local array of that size.

Both solutions aren't specially good. The first one implies using malloc
with all associated hassle, and the second risks allocating not enough
memory. C99 allows you to precisely allocate what you need and no more.

> Compound literals - sure, they might come in handy one day.

They do come handy, but again, they are not such a huge progress.


> A colossal math library?
> Hardly anyone needs it, and those who do are probably using something like
> Matlab anyway.
>

Maybe, maybe not, I have no data concerning this. In any case it
promotes portability (yes, I am not that stupid! :-) since it
defines a common interface for many math functions. Besides the control
you get from the abstracted FPU is very fine tuned.

You can portably set the rounding mode, for instance, and many other
things. In this sense the math library is quite a big step from C99.

> The real progress has been in the development of third-party libraries, many
> of which are at least a bit cross-platform.

That is a progress too, but (I do not know why) we never discuss them
in this group.

Maybe what frustrates me is that all this talk about "Stay in C89, C99
is not portable" is that it has taken me years of effort to implement
(and not all of it) C99 and that not even in this group, where we should
promote standard C C99 is accepted as what it is, the current standard.

I mean, each one of us has a picture of what C "should be". But if we
are going to get into *some* kind of consensus it must be the published
standard of the language, whether we like it or not.

For instance the fact that main() returns zero even if the programmer
doesn't specify it I find that an abomination. But I implemented that
because it is the standard even if I do not like it at all.


standard C

Chris F.A. Johnson

unread,
Jul 31, 2006, 6:19:35 PM7/31/06
to
On 2006-07-31, jacob navia wrote:
> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".
>
> Portability for them means the least common denominator.

Portability means the highest possible return for your effort.

> Write your code so that it will compile in all old and broken
> compilers, preferably in such a fashion that it can be moved with no
> effort from the embedded system in the coffe machine to the 64 bit
> processor in your desktop.
>
> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.

There's surprisingly little that makes programming C99 better than C89.

> Note that there is objectively speaking not a single useful
> program in C that can be ported to all machines that run the
> language.

That's strange. I have programs that I first wrote 20 years ago on
the Amiga, that I have compiled and run successfully, without any
changes, on MS-DOS, SunOS 4, FreeBSD, NetBSD, BSDi, and GNU/Linux.

I expect they would compile and execute successfully on any
standard C implementation.

--
Chris F.A. Johnson, author | <http://cfaj.freeshell.org>
Shell Scripting Recipes: | My code in this post, if any,
A Problem-Solution Approach | is released under the
2005, Apress | GNU General Public Licence

jacob navia

unread,
Jul 31, 2006, 6:27:59 PM7/31/06
to
Frederick Gotham a écrit :

>>Sure, you can do that. But as you know, there is no free lunch.
>>You pay for that "portability" by missing all the progress done
>>since 1989 in C.
>
>
>
> Present(verb) arguments in support of this statement -- I would like to
> debate this with you.
>
>

1) VLAs allow you to precisely allocate the memory the program needs
instead of using malloc (with all its associated problems) or having
to decide a maximum size for your local array, allocating too much
for most cases.

int fn(int n)
{
int tab[n];
}

allocates JUST what you need AT EACH CALL.

2) The math library is improved BIG time.
2A) You can portably set the rounding mode for instance, what you
could never do in C89 without using some compiler specific
stuff.
2B) Many new math functions allow you to reduce the number of
compiler dependent stuff in your code.

2C) The generic math feature allows you to change the precision
used by your program easily.
3) Mixing declarations and code allows you to declare variables
near the usage of it, making code more readable.

This are some points. There are others.

jacob navia

unread,
Jul 31, 2006, 6:30:38 PM7/31/06
to
Chris F.A. Johnson a écrit :

>>Note that there is objectively speaking not a single useful
>>program in C that can be ported to all machines that run the
>>language.
>
>
> That's strange. I have programs that I first wrote 20 years ago on
> the Amiga, that I have compiled and run successfully, without any
> changes, on MS-DOS, SunOS 4, FreeBSD, NetBSD, BSDi, and GNU/Linux.
>
> I expect they would compile and execute successfully on any
> standard C implementation.
>

The Amiga system is not an embedded system, and it is many ways very
similar to other command line environments.

I am not telling you that portable programs do not exists or that
it is not worthwhile trying to attain some degree of independence
from the underlying system. I am telling you that (as everything)
portability has some associated COST!

John Bode

unread,
Jul 31, 2006, 6:42:57 PM7/31/06
to

jacob navia wrote:
> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".
>
> Portability for them means the least common denominator.

It primarily means that conforming compilers have been implemented on a
wide variety of hardware and OS combinations, so that conforming code
on one platform can be expected to behave the same on any other
platform.

Secondarily, it means structuring your code so that it supports
multiple platforms concurrently with minimal effort, which I've had to
do on numerous occasions (the most painful being classic MacOS,
Solaris, and Windows 3.1).

And as far as supporting the "least common denominator", it's not my
fault that Microsoft went out of its way to make it nigh impossible to
code for Windows and *anything else* by "extending" C to such a
ridiculous degree. Nor is it my fault that the bulk of the lossage was
on the Windows side.

>
> Write your code so that it will compile in all old and broken
> compilers, preferably in such a fashion that it can be moved with no
> effort from the embedded system in the coffe machine to the 64 bit
> processor in your desktop.
>

What "old and broken" compilers are you referring to, jacob?

> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.
>

Really? How so?

> Note that there is objectively speaking not a single useful
> program in C that can be ported to all machines that run the
> language.
>

I beg to differ; I've written them. It *is* possible to write useful,
conforming apps. Not everything needs to run through a GUI.

> Not even the classic
>
> int main(void) { printf("hello\n");}
>
> Why?
>
> For instance, if we take that program above and we want to
> know if our printf did write something to stdout, we have to write
>
>
> int main(void) {
> int r=printf("hello\n");
> if (r < 0) {
> // what do we do here ???
> }
> }
>
> The error code returned by printf is nowhere specified. There is no
> portable way for this program to know what happened.
>

That's only sort of true; the return value is EOF if an error occurs,
otherwise the value is not EOF. So rewrite the above as

int main(void)
{
int r = printf("hello\n");
if (r == EOF)
{
/* handle error */
}

return 0;
}

> Since printf returns a negative value for an i/o error OR for a
> format error in the format string there is no portable way to
> discriminate between those two possibilitiess either.
>
> Obviously, network i/o, GUIs, threads, and many other stuff essential
> for modern programming is completely beyond the scope of "standard C"
> and any usage makes instantly your program non portable.
>

Which is why you wrap those sections.

Abstraction is a Good Thing, anyway.

> This means that effectively 100% of real C software is not portable to
> all machines and that "portability" is at best a goal to keep in
> mind by trying to build abstraction layers, but no more.
>
> This is taken to ridiculous heights with the polemic against C99, by
> some of those same 'regulars'.
>
> They first start yelling about "Standard C", and then... they do not
> mean standard C but some other obsolete standard. All that, in the name
> of "portability".
>
> Who cares about portability if the cost is higher than "usability"
> and easy of programming?
>

Talk to me when you've had to support Linux, MacOS, Windows, and MPE
concurrently.

Keith Thompson

unread,
Jul 31, 2006, 6:44:23 PM7/31/06
to
jacob navia <ja...@jacob.remcomp.fr> writes:
> Frederick Gotham a écrit :
>>>Sure, you can do that. But as you know, there is no free lunch.
>>>You pay for that "portability" by missing all the progress done
>>>since 1989 in C.

Or you pay for a few C99-specific features by losing a significant
degree of portability.

As many of us have been saying for a very long time, it's a tradeoff,
and different users will make different decisions about that tradeoff.
Pretending that it isn't, or that the choice is obvious, is
disingenuous.

>> Present(verb) arguments in support of this statement -- I would like
>> to debate this with you.
>
> 1) VLAs allow you to precisely allocate the memory the program needs
> instead of using malloc (with all its associated problems) or having
> to decide a maximum size for your local array, allocating too much
> for most cases.
>
> int fn(int n)
> {
> int tab[n];
> }
>
> allocates JUST what you need AT EACH CALL.

Yes. One cost is that there is no mechanism for handling allocation
failures. If I use malloc(), I can check whether it returned a null
pointer, and perhaps do something to handle the error (I can at least
shut down the program cleanly). With a VLA, if the allocation fails,
I get undefined behavior. In most environments, I'd expect this to
abort the program with an error message (not giving me a chance to do
any final cleanup) -- but the C99 standard allows arbitrarily bad
behavior.

> 2) The math library is improved BIG time.
> 2A) You can portably set the rounding mode for instance, what you
> could never do in C89 without using some compiler specific
> stuff.
> 2B) Many new math functions allow you to reduce the number of
> compiler dependent stuff in your code.
>
> 2C) The generic math feature allows you to change the precision
> used by your program easily.

I don't do much math programming, so I don't know how useful that is.

As a practical matter, this depends on a C99-conforming runtime
library, which is often a separate issue from the conformance of the
compiler.

> 3) Mixing declarations and code allows you to declare variables
> near the usage of it, making code more readable.

I agree that it's a nice feature, but it's easy to work around it when
it's missing. (Some people prefer not to mix declarations and
statements, thinking that keeping them separate improves program
structure; I don't necessarly agree, but I can see the point.)

Incidentally, the word "code" is ambiguous; it often refers to
everything in a C source files, not just statements. "Mixing
declarations and statements" is clearer.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Keith Thompson

unread,
Jul 31, 2006, 6:47:41 PM7/31/06
to

And if you had bothered to mention that to begin with, we probably
wouldn't be having this argument.

There is a tradeoff. Ignoring either side of that tradeoff is
foolish.

Yes, portability has a cost, in that you can't use C99 features.

Conversely, using C99 features has a cost, in that you lose a
significant degree of portability.

--

Frederick Gotham

unread,
Jul 31, 2006, 6:51:00 PM7/31/06
to
jacob navia posted:

>>>Sure, you can do that. But as you know, there is no free lunch.
>>>You pay for that "portability" by missing all the progress done
>>>since 1989 in C.

>> Present(verb) arguments in support of this statement -- I would like to
>> debate this with you.

> 1) VLAs allow you to precisely allocate the memory the program needs
> instead of using malloc (with all its associated problems) or having
> to decide a maximum size for your local array, allocating too much
> for most cases.
>
> int fn(int n)
> {
> int tab[n];
> }
>
> allocates JUST what you need AT EACH CALL.


C99 added a few new features to C.

C++ added a boat load of new features to C.

Even C++ doesn't have VLA's, because it finds efficiency to be more
valuable.

You can do the following in C++:

unsigned const len = 5;
int array[len];

But you *can't* do the following:

unsigned len = GetValueAtCompileTime();
int array[len];

The length of an array must be a compile-time constant.

Arrays whose length is known at compile time are far more efficient to work
with. Therefore, in C++, they decreed that one should be explicit about
dynamic memory allocation:

unsigned len = GetValueAtRuntime();

int *p = new unsigned[len];

delete p;

Or the C equivalent:

int *p = malloc(len * sizeof *p);
free(p);

I simply just don't like VLA's, and will never use them.


> 2) The math library is improved BIG time.
> 2A) You can portably set the rounding mode for instance, what you
> could never do in C89 without using some compiler specific
> stuff.
> 2B) Many new math functions allow you to reduce the number of
> compiler dependent stuff in your code.
> 2C) The generic math feature allows you to change the precision
> used by your program easily.


I haven't written maths-intensive programs, so I'm not qualified to comment
on this.


> 3) Mixing declarations and code allows you to declare variables
> near the usage of it, making code more readable.


Yes, I like to define variables right where I need them.

NB: I wasn't arguing about the advantages of using C99 over using C89, but
rather any perceived disadvantages (efficiency wise) in writing strictly
portable code.

--

Frederick Gotham

Keith Thompson

unread,
Jul 31, 2006, 6:52:33 PM7/31/06
to
Frederick Gotham <fgot...@SPAM.com> writes:
> jacob navia posted:
[...]

>> Not even the classic
>>
>> int main(void) { printf("hello\n");}
>>
>> Why?
>>
>> For instance, if we take that program above and we want to
>> know if our printf did write something to stdout, we have to write
>>
>>
>> int main(void) {
>> int r=printf("hello\n");
>> if (r < 0) {
>> // what do we do here ???
>> }
>> }
>>
>> The error code returned by printf is nowhere specified. There is no
>> portable way for this program to know what happened.
>
>
> Nor would I care what happened. If a system can't reliably print a few
> miserable characters to the screen, then I wouldn't waste electricity by
> plugging it in.
[...]

Several points.

What screen?

Both programs above invoke undefined behavior, because they both call
printf() with no prototype in scope. The fix is to add
"#include <stdio.h>" to the top of each.

printf() *can* fail. For example, what if the program's stdout is
redirected (in some system-specific manner) to a disk file, and the
file system has run out of space? If you check the result of printf()
for errors, there are several things you can do. You can try to print
an error message to stderr, which may succeed even if printing to
stdout has failed. Or you can just abort the program with
"exit(EXIT_FAILURE);".

Or, as most programs do, you can ignore the error and blindly continue
running. (I admit this is what I usually do myself.)

Frederick Gotham

unread,
Jul 31, 2006, 6:58:30 PM7/31/06
to
Keith Thompson posted:

> Or, as most programs do, you can ignore the error and blindly continue
> running. (I admit this is what I usually do myself.)


I do this myself in quite a few places.

For instance, if I were allocating upwards of a megabyte of memory, I would
probably take precautions:

int *const p = malloc(8388608 / CHAR_BIT
+ !!(8388608 % CHAR_BIT));

if(!p) SOS();

But if I'm allocating less than a kilobytes... I probably won't bother most
of the time. (The system will already have ground to a halt by that stage if
it has memory allocation problems.)

--

Frederick Gotham

jacob navia

unread,
Jul 31, 2006, 6:58:37 PM7/31/06
to
John Bode a écrit :

>
>
> Talk to me when you've had to support Linux, MacOS, Windows, and MPE
> concurrently.
>

lcc-win32 has customers under linux, windows and many embedded systems
without any OS (or, to be more precise, with an OS that is part
of the compiled program)

Ben Pfaff

unread,
Jul 31, 2006, 6:55:23 PM7/31/06
to
Keith Thompson <ks...@mib.org> writes:

> printf() *can* fail. For example, what if the program's stdout is
> redirected (in some system-specific manner) to a disk file, and the
> file system has run out of space? If you check the result of printf()
> for errors, there are several things you can do. You can try to print
> an error message to stderr, which may succeed even if printing to
> stdout has failed. Or you can just abort the program with
> "exit(EXIT_FAILURE);".

One reasonable option may be to flush stdout before exiting the
program, then call ferror to check whether there was an error.
If there was, terminate the program with an error (after
attempting to report it to stderr).

Some of my programs do this, but only the ones that I care about
a lot.
--
"This is a wonderful answer.
It's off-topic, it's incorrect, and it doesn't answer the question."
--Richard Heathfield

dco...@connx.com

unread,
Jul 31, 2006, 7:00:30 PM7/31/06
to

jacob navia wrote:
> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".
>
> Portability for them means the least common denominator.

Portability means never having to say you're sorry. Portability means
conforming to a formally accepted written standard which defines how
things ought to behave.

> Write your code so that it will compile in all old and broken
> compilers, preferably in such a fashion that it can be moved with no
> effort from the embedded system in the coffe machine to the 64 bit
> processor in your desktop.

Do you really overlook the value of being able to do that?

> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.

Portable can be portable to C89, to C99 or to an implementation
document. The degree of portability achieved will depend upon how well
accepted and debugged the standard in use was. If I write to the C99
standard, I am writing portable code. It is portable to C99.

> Note that there is objectively speaking not a single useful
> program in C that can be ported to all machines that run the
> language.

How about a useful program in C that runs on 100 million machines of
various architectures and is maintained over a 20 year period. Does
that sound useful to you?

> Not even the classic
>
> int main(void) { printf("hello\n");}
>
> Why?

Other than the lack of a prototype for printf(), I don't see anything
terribly wrong with it. The big problem with failure of printf() is
that we are at a bit of a loss as to how to report the problem n'est ce
pas?

> For instance, if we take that program above and we want to
> know if our printf did write something to stdout, we have to write
>
>
> int main(void) {
> int r=printf("hello\n");
> if (r < 0) {
> // what do we do here ???
> }
> }
>
> The error code returned by printf is nowhere specified. There is no
> portable way for this program to know what happened.

You know that the printf() failed. You may not know why and perror()
may or may not be useful. How would you go about repairing this
defect?

>
> Since printf returns a negative value for an i/o error OR for a
> format error in the format string there is no portable way to
> discriminate between those two possibilitiess either.

For a format error, it is possible to know because you can check your
format.

> Obviously, network i/o, GUIs, threads, and many other stuff essential
> for modern programming is completely beyond the scope of "standard C"
> and any usage makes instantly your program non portable.

It makes the part of the program that uses network I/O, a GUI, threads
or other essential tasks non-portable. Here, we will generally resort
to another standard. We can use TCP/IP for network programming. We
can use POSIX threads for threading. For the GUI, we may have to use a
proprietary standard like wxWidgets or an operating system specific API
like the Windows API. In each of these cases we are still doing
standards based computing, but we are not using ANSI/ISO standards for
the parts not covered by the more fundamental level.

> This means that effectively 100% of real C software is not portable to
> all machines and that "portability" is at best a goal to keep in
> mind by trying to build abstraction layers, but no more.

Did you know that 99.997% of all statistics are made up?
I work on a software system with hundreds of thousands of lines of
code.
It runs on Solaris, AIX, Windows, Linux, MVS, OpenVMS (and many others)
against dozens of database systems. Do you imagine that such a thing
would be remotely feasible without paying detailed attention to
standards?

> This is taken to ridiculous heights with the polemic against C99, by
> some of those same 'regulars'.

I agree that C99 is a favorite whipping boy for no reason that I can
glean. There are not a lot adopters, but many of the features are very
desirable. VLAs (in particular) are worth their weight in gold.

> They first start yelling about "Standard C", and then... they do not
> mean standard C but some other obsolete standard. All that, in the name
> of "portability".

C99 is standard C. Other standards must be prefaced by the name of the
standard (IMO-YMMV). That's because C99 legally replaces the previous
C standard.

> Who cares about portability if the cost is higher than "usability"

Nobody does.

> and easy of programming?

Adhering to standards makes programming much, much easier. I
programmed in C before there was any formal standard approved. It was
really awful, and every implementation was so different that you had to
completely rewrite things constantly to go from one compiler vendor to
the next, even on the same physical architecture.

>
> jacob

I don't understand why anyone would complain against standards.
Programming is practically impossible without them.

jacob navia

unread,
Jul 31, 2006, 7:04:25 PM7/31/06
to
Keith Thompson a écrit :

> jacob navia <ja...@jacob.remcomp.fr> writes:
>
>>Frederick Gotham a écrit :
>>
>>>>Sure, you can do that. But as you know, there is no free lunch.
>>>>You pay for that "portability" by missing all the progress done
>>>>since 1989 in C.
>
>
> Or you pay for a few C99-specific features by losing a significant
> degree of portability.

Well but this group is about STANDARD C or not?

If we do not agree about what standard C is, we can use the standard.

But if we do not even agree what standard C is ther can't be
any kind of consensus in this group you see?

The talk about "Standard C" then, is just hollow words!!!

Ben Pfaff

unread,
Jul 31, 2006, 7:05:39 PM7/31/06
to
Frederick Gotham <fgot...@SPAM.com> writes:

> For instance, if I were allocating upwards of a megabyte of memory, I would
> probably take precautions:
>
> int *const p = malloc(8388608 / CHAR_BIT
> + !!(8388608 % CHAR_BIT));
>
> if(!p) SOS();
>
> But if I'm allocating less than a kilobytes... I probably won't bother most
> of the time. (The system will already have ground to a halt by that stage if
> it has memory allocation problems.)

Why not use a wrapper function that will always do the right
thing?
--
"The fact that there is a holy war doesn't mean that one of the sides
doesn't suck - usually both do..."
--Alexander Viro

jacob navia

unread,
Jul 31, 2006, 7:10:25 PM7/31/06
to
dco...@connx.com a écrit :

>
>
> C99 is standard C. Other standards must be prefaced by the name of the
> standard (IMO-YMMV). That's because C99 legally replaces the previous
> C standard.
>

This is the most important thing I wanted with my previous message.

That we establish a consensus here about what standard C means.

And it can't mean anything else as the *current* C standard.

I have been working for years in a C99 implementation. and I wanted
that at least in this group, that is supposed to be centered around
standard C we establish that C99 *is* the standard weven if we do
not like this or that feature.

dco...@connx.com

unread,
Jul 31, 2006, 7:13:06 PM7/31/06
to
"Frederick Gotham" <fgot...@SPAM.com> wrote in message
news:oPvzg.12108$j7.3...@news.indigo.ie...
[snip]

> Arrays whose length is known at compile time are far more efficient to work
> with.

I doubt this statement.

On stack based machines, it's nothing more than a subtraction. Whether
the value is passed in or known at compile time makes no difference.

[snip]

jacob navia

unread,
Jul 31, 2006, 7:19:33 PM7/31/06
to
dco...@connx.com a écrit :

I implemented this by making the array a pointer, that
gets its value automagically when the function starts by making
a subtraction from the stack pointer. Essentially

int fn(int n)
{
int tab[n];

...
}

becomes

int fn(int n)
{
int *tab = alloca(n*sizeof(int));
}

The access is done like any other int *...

Tom St Denis

unread,
Jul 31, 2006, 7:34:23 PM7/31/06
to
jacob navia wrote:
> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".
>
> Portability for them means the least common denominator.

No it means making wise design choices.

> Write your code so that it will compile in all old and broken
> compilers, preferably in such a fashion that it can be moved with no
> effort from the embedded system in the coffe machine to the 64 bit
> processor in your desktop.

Why? I target C99 with my code. To me "portable" means C99. I
consider it a hack if I have to support something outside of it [e.g.
Visual C lack of long long for instance].

> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.

C99 programs are portable.

<snip nonsense>

Even with all the latest doodahs of C99 you still are not assured to
have a TTY or a console, file system or even a heap, etc...

Big deal?

No one expects a 3D video game to work on an 8051.

On the otherhand, one would expect some non-interface type routine to
work anywhere.

My own math lib [LibTomMath] has been built on things as low as an 8086
with TurboC all the way up through the various 64-bit servers and
consoles. Without sacrificing too much speed or ANY functionality.

Similarly my crypto code is used pretty much anywhere without hacking
for this compiler, that compiler, etc.

Tom

Keith Thompson

unread,
Jul 31, 2006, 7:51:20 PM7/31/06
to
"John Bode" <john...@my-deja.com> writes:
> jacob navia wrote:
[...]

>> Not even the classic
>>
>> int main(void) { printf("hello\n");}
>>
>> Why?
>>
>> For instance, if we take that program above and we want to
>> know if our printf did write something to stdout, we have to write
>>
>>
>> int main(void) {
>> int r=printf("hello\n");
>> if (r < 0) {
>> // what do we do here ???
>> }
>> }
>>
>> The error code returned by printf is nowhere specified. There is no
>> portable way for this program to know what happened.
>>
>
> That's only sort of true; the return value is EOF if an error occurs,
> otherwise the value is not EOF. So rewrite the above as
>
> int main(void)
> {
> int r = printf("hello\n");
> if (r == EOF)
> {
> /* handle error */
> }
>
> return 0;
> }
[...]

That's incorrect. C99 7.19.6.3p3:

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

The "if (r < 0)" test is correct.

J. J. Farrell

unread,
Jul 31, 2006, 8:11:32 PM7/31/06
to

jacob navia wrote:
>
> I am not telling you that portable programs do not exists or that
> it is not worthwhile trying to attain some degree of independence
> from the underlying system. I am telling you that (as everything)
> portability has some associated COST!

Why are you telling us something that's blatantly obvious, and that we
all know?

Since we're stating the obvious, the question to be asked on each
occasion is whether the COST of portability exceeds the COST of
non-portability. In my experience, for the sort of work I do, it's
always been better to steer hard towards the portable end of the range.

Andrew Poelstra

unread,
Jul 31, 2006, 8:11:38 PM7/31/06
to
On 2006-07-31, Ben Pfaff <b...@cs.stanford.edu> wrote:
> Frederick Gotham <fgot...@SPAM.com> writes:
>
>> For instance, if I were allocating upwards of a megabyte of memory, I would
>> probably take precautions:
>>
>> int *const p = malloc(8388608 / CHAR_BIT
>> + !!(8388608 % CHAR_BIT));
>>
>> if(!p) SOS();
>>
>> But if I'm allocating less than a kilobytes... I probably won't bother most
>> of the time. (The system will already have ground to a halt by that stage if
>> it has memory allocation problems.)
>
> Why not use a wrapper function that will always do the right
> thing?

What would such a wrapper do? I've written a few that do things like
attempt to settle for less memory, return memory from a pre-allocated
buffer (if malloc() succeeded, I'd take a little extra while the getting
was good), or in one case I informed the user and gave him the option to
either kill other memory-intensive programs or simply die.

However, the second of those options requires an equivilant wrapper for
free() because if I'm manually hacking memory around it's far too easy
to end up with UB. The others aren't acceptable in certain situations.

More importantly, no matter what you do, the function calling the
wrapper needs to do essentially the same stuff as a function calling
malloc() directly in the case of a critical memory error.

--
Andrew Poelstra <website down>
To reach my email, use <email also down>
New server ETA: 42

Keith Thompson

unread,
Jul 31, 2006, 8:16:12 PM7/31/06
to
Frederick Gotham <fgot...@SPAM.com> writes:
> jacob navia posted:
>>>>Sure, you can do that. But as you know, there is no free lunch.
>>>>You pay for that "portability" by missing all the progress done
>>>>since 1989 in C.
>
>>> Present(verb) arguments in support of this statement -- I would like to
>>> debate this with you.
>
>> 1) VLAs allow you to precisely allocate the memory the program needs
>> instead of using malloc (with all its associated problems) or having
>> to decide a maximum size for your local array, allocating too much
>> for most cases.
>>
>> int fn(int n)
>> {
>> int tab[n];
>> }
>>
>> allocates JUST what you need AT EACH CALL.
>
>
> C99 added a few new features to C.

Yes.

> C++ added a boat load of new features to C.

Yes and no. C++ has a boat load of features that aren't in C, but it
didn't add them to C; it added them to C++. Yes, I'm being
ridiculously picky about wording, but it is an important distinction.
C++ did not attempt to *replace* C. C99, in a very real sense, did.

> Even C++ doesn't have VLA's, because it finds efficiency to be more
> valuable.

<OT>
I don't believe that's the reason. The C++98 standard is based on the
C90 standard, which doesn't/didn't have VLAs, and C++ didn't add them.
I would be completely unsurprised if a future C++ standard adopted
VLAs from C99.

On the other hand, the C++ standard library provides other features
that can be used in place of VLAs.
</OT>

Keith Thompson

unread,
Jul 31, 2006, 8:17:19 PM7/31/06
to

If that's literally true, then sizeof tab will yield an incorrect
result.

Keith Thompson

unread,
Jul 31, 2006, 8:20:33 PM7/31/06
to

In my opinion, that's an extremely unwise approach.

In many cases, the fact that your program is running out of memory
will have no effect on the system as a whole; many systems place
limits on how much memory a single program (<OT>process</OT>) may
allocate, and those limits are typically much smaller than the total
amount of memory available to the system. This is particularly true
for multi-user systems.

You should always check the result of every call to malloc(). If you
don't want to do the check explicitly, write a wrapper.

Keith Thompson

unread,
Jul 31, 2006, 8:21:53 PM7/31/06
to
Ben Pfaff <b...@cs.stanford.edu> writes:
> Keith Thompson <ks...@mib.org> writes:
>> printf() *can* fail. For example, what if the program's stdout is
>> redirected (in some system-specific manner) to a disk file, and the
>> file system has run out of space? If you check the result of printf()
>> for errors, there are several things you can do. You can try to print
>> an error message to stderr, which may succeed even if printing to
>> stdout has failed. Or you can just abort the program with
>> "exit(EXIT_FAILURE);".
>
> One reasonable option may be to flush stdout before exiting the
> program, then call ferror to check whether there was an error.
> If there was, terminate the program with an error (after
> attempting to report it to stderr).
>
> Some of my programs do this, but only the ones that I care about
> a lot.

Yes, that's probably better than silently ignoring the error.

One possible drawback is that it doesn't catch the error until the
program is just about to terminate.

Al Balmer

unread,
Jul 31, 2006, 8:34:08 PM7/31/06
to
On Tue, 01 Aug 2006 01:10:25 +0200, jacob navia
<ja...@jacob.remcomp.fr> wrote:

>dco...@connx.com a écrit :
>>
>>
>> C99 is standard C. Other standards must be prefaced by the name of the
>> standard (IMO-YMMV). That's because C99 legally replaces the previous
>> C standard.
>>
>
>This is the most important thing I wanted with my previous message.
>
>That we establish a consensus here about what standard C means.
>

There's no consensus needed about a matter of fact which nobody
contests. However, we can understand that C99 is the current C
standard while also recognizing that it is not universally implemented
and that maximum portability often means that we must forgo some or
all of the new features it introduced. (That's a rhetorical "we" and
does not necessarily include you.)

We (most of us) also understand that portability is a worthwhile goal,
often more important to us and our work than being able to use all the
latest features of the language.

>And it can't mean anything else as the *current* C standard.
>
>I have been working for years in a C99 implementation. and I wanted
>that at least in this group, that is supposed to be centered around
>standard C we establish that C99 *is* the standard weven if we do
>not like this or that feature.

Why do you think this needs to be "established"? It's self-evident and
no one is contesting it.

In this thread, what has been contested is much of the ridiculous
rhetoric you indulged in in your initial post. You now seem to have
changed the subject.

--
Al Balmer
Sun City, AZ

Keith Thompson

unread,
Jul 31, 2006, 8:43:08 PM7/31/06
to
jacob navia <ja...@jacob.remcomp.fr> writes:
> dco...@connx.com a écrit :
>> C99 is standard C. Other standards must be prefaced by the name of
>> the standard (IMO-YMMV). That's because C99 legally replaces the
>> previous C standard.
>
> This is the most important thing I wanted with my previous message.
>
> That we establish a consensus here about what standard C means.
>
> And it can't mean anything else as the *current* C standard.

First, I disagree with the use of the term "legally". ISO is not a
governmental body, and the C standard does not have the force of law.
Nobody is going to arrest a user or an implementer for failing to
conform to it.

Standards do not exist in a vacuum. The purpose of a language
standard is to provide a contract (I don't necessarily mean that in
any legal sense) between users and implementers. If implementers
provide implementations that conform to the standard, and if users
write code that conforms to the standard, then that code will work
correctly with those implementations.

It is a fact (and, IMHO, an unfortunate one) that the C99 standard has
not been as successful as the C90 standard. There are reasons for
this; I won't repeat them here. But the result is that, in the real
world, I can write code that conforms to the C99 standard, but not be
able to get it to work properly on some platforms that I care about.
If I instead write code that conforms to both the C90 and C99
standards, I have a much better chance of getting it to work portably.

> I have been working for years in a C99 implementation. and I wanted
> that at least in this group, that is supposed to be centered around
> standard C we establish that C99 *is* the standard weven if we do
> not like this or that feature.

This isn't about whether we like or dislike any particular features of
C99. The issue is that those features *are not as widely available*
as the features defined by the C90 standard.

Your approach seems to be just to ignore this fact, and encourage
users to write C99-dependent code without worrying about portability.
Most of the rest of us, on the other hand, prefer to let people know
what the tradeoffs are.

There's plenty of discussion of C99 here. I regularly post quotations
from the standard; when I do, they're usually from the C99 standard or
from the n1124 draft. If someone posts code that mixes declarations
and statements, we don't say that that's illegal in C; rather we say,
truthfully, that it's legal in C99 but illegal in C90, and *explain
the tradeoffs*.

Back in the early 1990s, I'm sure you would have found plenty of
advice in this newsgroup (or its ancestor, net.lang.c; I don't
remember when the transition was) about programming in K&R C, and
writing code that's legal in both K&R C and ANSI C. The 1990 ISO C
standard had been released, and it was the *official* definition of
the language, but real-world programmers still had to deal with the
fact that it wasn't yet universally supported.

We don't stop talking about an old standard when a new one comes out;
we stop talking about an old standard when it becomes irrelevant. The
C90 standard is still very relevant.

(comp.std.c has an even stronger emphasis on C99, since any future
standards or technical corrigenda will be based on C99, not C90.)

Keith Thompson

unread,
Jul 31, 2006, 8:45:23 PM7/31/06
to

We talk about Standard C (C99) all the time. We're doing so right now.

We also talk about the previous standard, and occasionally about the
de facto standard before that (K&R1, Appendix A).

Keith Thompson

unread,
Jul 31, 2006, 8:58:52 PM7/31/06
to
Andrew Poelstra <fake.a...@wp.net> writes:
> On 2006-07-31, Ben Pfaff <b...@cs.stanford.edu> wrote:
>> Frederick Gotham <fgot...@SPAM.com> writes:
>>
>>> For instance, if I were allocating upwards of a megabyte of
>>> memory, I would probably take precautions:
>>>
>>> int *const p = malloc(8388608 / CHAR_BIT
>>> + !!(8388608 % CHAR_BIT));
>>>
>>> if(!p) SOS();
>>>
>>> But if I'm allocating less than a kilobytes... I probably won't
>>> bother most of the time. (The system will already have ground to a
>>> halt by that stage if it has memory allocation problems.)
>>
>> Why not use a wrapper function that will always do the right
>> thing?
>
> What would such a wrapper do?

In the simplest case, it could abort the program with an error message
if malloc() fails. This isn't ideal, but it's certainly better than
ignoring an allocation failure.

Flash Gordon

unread,
Jul 31, 2006, 8:19:49 PM7/31/06
to

As you know very well we discuss C99, C95, C90 and even pre-ANSI C when
appropriate. Why do you object so strongly to people not being told when
something is a C99 feature and so not portable to such common
implementations as MS VC++?

Personally I would *far* rather use C99 but I have to support MS VC++
and at least two older versions -f gcc and glibc plus the C library on
another OS that does not support C99 as yet. Oh, and I could be asked at
any time about supporting some other OS for which there might not be a
C99 compiler around. Such situations are very common.

So if you want to discus something about C99 go ahead. If you want to
tell people that in C99 they can do something go ahead. However, don't
claim that everyone can use C99 or make false claims about
implementations supporting C99 when they don't.
--
Flash Gordon
Still sigless on this computer.

Keith Thompson

unread,
Jul 31, 2006, 9:25:52 PM7/31/06
to
Flash Gordon <sp...@flash-gordon.me.uk> writes:
[...]

> As you know very well we discuss C99, C95, C90 and even pre-ANSI C
> when appropriate. Why do you object so strongly to people not being
> told when something is a C99 feature and so not portable to such
> common implementations as MS VC++?

I think you meant to drop the first "not" in that last sentence;
"people not being told" should be "people being told".

dco...@connx.com

unread,
Jul 31, 2006, 9:34:34 PM7/31/06
to

Keith Thompson wrote:
> jacob navia <ja...@jacob.remcomp.fr> writes:
> > dco...@connx.com a écrit :
> >> C99 is standard C. Other standards must be prefaced by the name of
> >> the standard (IMO-YMMV). That's because C99 legally replaces the
> >> previous C standard.
> >
> > This is the most important thing I wanted with my previous message.
> >
> > That we establish a consensus here about what standard C means.
> >
> > And it can't mean anything else as the *current* C standard.
>
> First, I disagree with the use of the term "legally". ISO is not a
> governmental body, and the C standard does not have the force of law.
> Nobody is going to arrest a user or an implementer for failing to
> conform to it.

ANSI is connected to the U.S. government and (along with NIST) is used
to establish standards in the United States. While standard adoption
is 'voluntary' there can still be legal ramifications. For instance,
if I stamp the head of my bolt with a certain number of diamond shapes
on it, that is a claim of adherence to a standard. If the claim is
false, the manufacturer could get sued, possibly go to jail, etc.
Sometimes, formal standards do get adopted with more or less legal
weight, which would vary from country to country and standard to
standard. I can easily imagine legal problems for a C compiler vendor
who claimed in their advertizing that their compiler adhered to the
ANSI/ISO C standard but in fact, failed badly on many measures.

Here is an interesting quote that I found:
"Standards, unlike many other technical papers and reports, are
quasi-legal documents. Standards are used as evidence, either to
substantiate or refute points, in courts of law. Standards also become
legal documents if adopted by various governments or regulatory
agencies. When this happens, the content and decisions in a standard
carry more weight, and the process by which they are developed falls
under much more scrutiny, making ANSI accreditation especially
valuable."

I am certainly in wholehearted agreement with the main thrust of your
post, but wanted to point out a nuance of potential legal ramification,
though the documents themselves do not embody law.
[snip]

Dik T. Winter

unread,
Jul 31, 2006, 9:49:54 PM7/31/06
to
In article <44ce9005$0$850$ba4a...@news.orange.fr> jacob navia <ja...@jacob.remcomp.fr> writes:
...

> I implemented this by making the array a pointer, that
> gets its value automagically when the function starts by making
> a subtraction from the stack pointer. Essentially

Yup, standard since about 1960 when they were introduced. But:


> int fn(int n)
> {
> int *tab = alloca(n*sizeof(int));
> }
>
> The access is done like any other int *...

So the access is inherently less efficient (and that was the discussion
about).
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Dik T. Winter

unread,
Jul 31, 2006, 9:47:14 PM7/31/06
to
In article <1154387586.3...@m73g2000cwd.googlegroups.com> dco...@connx.com writes:
> "Frederick Gotham" <fgot...@SPAM.com> wrote in message
> news:oPvzg.12108$j7.3...@news.indigo.ie...
> > Arrays whose length is known at compile time are far more efficient to work
> > with.
>
> I doubt this statement.
>
> On stack based machines, it's nothing more than a subtraction. Whether
> the value is passed in or known at compile time makes no difference.

If you allocate runtime lenghth arrays on the stack, you need indirection
if you have to allocate more than one such arrays at a level (especially
if there are multi-dimensional arrays involved). When Algol-60 introduced
runtime length arrays there have been reports written and long discussions
about how to implement it. It was not for nothing that Wirth removed them
in Pascal.

Keith Thompson

unread,
Jul 31, 2006, 9:50:46 PM7/31/06
to

Ok, that's a good point.

It seems to me (I'm hardly an expert) that this is partly a specific
case of the more general principle that if you falsely claim
conformance to something, you've committed fraud. For example, if I
sell widgets while claiming that each widget conforms to Ralph's
Pretty Good Widget Standard, I can be sued by my customers if in fact
I've deliberately violated clause 4.2.

On the other hand, that's not all there is to it; an ANSI or ISO
standard undoubtedly has some quasi-legal standing beyond that enjoyed
by any of Ralph's Pretty Good Standards.

Whether the "quasi" or the "legal" part is more significant depends on
what you're talking about.

Dik T. Winter

unread,
Jul 31, 2006, 9:57:52 PM7/31/06
to
In article <44ce8b1c$0$859$ba4a...@news.orange.fr> jacob navia <ja...@jacob.remcomp.fr> writes:
> John Bode a écrit :
> > Talk to me when you've had to support Linux, MacOS, Windows, and MPE
> > concurrently.
>
> lcc-win32 has customers under linux, windows and many embedded systems
> without any OS (or, to be more precise, with an OS that is part
> of the compiled program)

Where can I find lcc-win32 for linux?

Default User

unread,
Aug 1, 2006, 12:52:34 AM8/1/06
to
jacob navia wrote:

> In this group there is a bunch of people that call themselves
> 'regulars' that insist in something called "portability".


Please stop trolling the newsgroup.

Brian

Old Wolf

unread,
Aug 1, 2006, 2:17:18 AM8/1/06
to
jacob navia wrote:
> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".

Funny how all the "portability is a myth" people write
all their code on x86.

Old Wolf

unread,
Aug 1, 2006, 2:18:55 AM8/1/06
to
Ben Pfaff wrote (re. error checking of mallc):

>
> Why not use a wrapper function that will always do the right
> thing?

That reminds me of the course where I learned C. The tutor advised:

#define MALLOC(type, n) ((type *)malloc((n) * sizeof(type))

jaysome

unread,
Aug 1, 2006, 2:22:45 AM8/1/06
to
On Mon, 31 Jul 2006 15:55:23 -0700, Ben Pfaff <b...@cs.stanford.edu>
wrote:

>Keith Thompson <ks...@mib.org> writes:
>
>> printf() *can* fail. For example, what if the program's stdout is
>> redirected (in some system-specific manner) to a disk file, and the
>> file system has run out of space? If you check the result of printf()
>> for errors, there are several things you can do. You can try to print
>> an error message to stderr, which may succeed even if printing to
>> stdout has failed. Or you can just abort the program with
>> "exit(EXIT_FAILURE);".
>
>One reasonable option may be to flush stdout before exiting the
>program, then call ferror to check whether there was an error.
>If there was, terminate the program with an error (after
>attempting to report it to stderr).

Did you have a test case for this code? If so, did you ever achieve
decision coverage in the case where ferror() gave an error? That would
be remarkable if you did, and I would like to hear how you did it. The
only way I know how to do it is with preprocessor macros, and even
then it's not the greatest.

Best regards
--
jay

Richard Heathfield

unread,
Aug 1, 2006, 3:22:22 AM8/1/06
to
jacob navia said:

> Richard Heathfield a écrit :
>> There isn't all that much progress in C. What did C99 give us?
>
> True, C99 didn't really advance the language that much, but it has some
> good points.

Nothing I'd bother to include in a letter home, but one or two tiny good
points. Nothing there worth breaking your program's portability over.

> Anyway, if we are going to stick to standard C, let's agree
> that standard C is Standard C as defined by the standards comitee.

K&R C is the original C language, and it's topical here in clc.
C90 is the current de facto standard, and is topical here in clc.
C99 is the current de jure standard, and is topical here in clc.

We discuss them all here. We didn't abandon K&R C just because of C90, and
we're not going to abandon C90 just because of C99.

>> Mixed declarations? Sugar.
> // comments? More sugar. VLAs? More sugar.
>
> And what do you have against sugar?
> You drink your coffee without it?

My point, as I'm sure you know, is that these are trivial changes. If I'm
going to risk the portability of my code, I want a HUGE
functionality/convenience payoff in return. C++ just about gives me that,
which is why I sometimes do use C++ - but C99 certainly does not.

> I mean, C is just syntatic sugar for assembly language. Why
> not program in assembly then?

For which assembly language is C syntactic sugar? There's more to computers
than "the computer sitting on Mr Navia's desk".

> Mixed declarations are a progress in the sense that they put the
> declaration nearer the usage of the variable, what makes reading
> the code much easier, specially in big functions.

Fine. When C99 is as widespread as C90 currently is, I'll be glad to take
advantage of them.

> True, big functions are surely not a bright idea, but they happen :-)
>
> I accept that this is not a revolution, or a really big progress in C
> but it is a small step, what is not bad.

It's not bad provided it works. It's foolish to adopt a feature just because
you can, if having adopted that feature you then find that your code won't
compile on some of your target platforms.

> VLAs are a more substantial step since it allows to allocate precisely
> the memory the program needs without having to over-allocate or risk
> under allocating arrays.

I see nothing they give that can't be got from a quick malloc.

>
> Under C89 you have to either:
> 1) allocate memory with malloc

Works for me.

> 2) Decide a maximum size and declare a local array of that size.

Not so good.

>
> Both solutions aren't specially good. The first one implies using malloc
> with all associated hassle,

What hassle? You ask for memory, you get a pointer to it or a NULL, end of
problem. And you get to find out whether it worked, rather than have your
program crash out on you if N is way too large for any reason.

> and the second risks allocating not enough
> memory. C99 allows you to precisely allocate what you need and no more.

So does malloc.


> > Compound literals - sure, they might come in handy one day.
>
> They do come handy, but again, they are not such a huge progress.

For once, we agree.

>> A colossal math library?
>> Hardly anyone needs it, and those who do are probably using something
>> like Matlab anyway.
>>
>
> Maybe, maybe not, I have no data concerning this. In any case it
> promotes portability (yes, I am not that stupid!

How stupid are you, exactly?

> :-) since it
> defines a common interface for many math functions. Besides the control
> you get from the abstracted FPU is very fine tuned.

<shrug> Since hardly anyone needs it, who cares?

> You can portably set the rounding mode, for instance, and many other
> things. In this sense the math library is quite a big step from C99.

Only for people for whom it's useful, which is almost nobody.

>> The real progress has been in the development of third-party libraries,
>> many of which are at least a bit cross-platform.
>
> That is a progress too, but (I do not know why) we never discuss them
> in this group.

Because There Are Other Newsgroups For Discussing Them. If you learn nothing
else from this reply, learn this, at least: comp.lang.c is not a dumping
ground for anything Jacob Navia finds interesting. It is a newsgroup for
the discussion of the C language. Other stuff is also very interesting.
Other stuff is also very useful. Other stuff is also great fun. But other
stuff is discussed in Other Newsgroups. In this newsgroup, we discuss C. In
other newsgroups, we discuss those other things.


> Maybe what frustrates me is that all this talk about "Stay in C89, C99
> is not portable" is that it has taken me years of effort to implement
> (and not all of it) C99

Not all of it. So you don't even have a conforming compiler, and yet you're
suggesting we move to C99? Dream on.

> and that not even in this group, where we should
> promote standard C C99 is accepted as what it is, the current standard.

It's the current de jure standard. It will never become the de facto
standard until it meets the same needs that C90 currently meets.

> I mean, each one of us has a picture of what C "should be". But if we
> are going to get into *some* kind of consensus it must be the published
> standard of the language, whether we like it or not.

But it isn't a consensus. If it were a consensus, it would be widely
implemented. And it isn't, so it isn't.

> For instance the fact that main() returns zero even if the programmer
> doesn't specify it I find that an abomination. But I implemented that
> because it is the standard even if I do not like it at all.

Fine, but bright people will still explicitly return 0 from main - not just
because omitting it is indeed an abomination, but also to keep their
programs portable to all C90 implementations as well as all C99
implementations.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Richard Heathfield

unread,
Aug 1, 2006, 3:28:07 AM8/1/06
to
Old Wolf said:

How pointless.

Richard Heathfield

unread,
Aug 1, 2006, 3:30:28 AM8/1/06
to
Ben Pfaff said:

> Frederick Gotham <fgot...@SPAM.com> writes:
>
>> For instance, if I were allocating upwards of a megabyte of memory, I
>> would probably take precautions:
>>
>> int *const p = malloc(8388608 / CHAR_BIT
>> + !!(8388608 % CHAR_BIT));
>>
>> if(!p) SOS();
>>
>> But if I'm allocating less than a kilobytes... I probably won't bother
>> most of the time. (The system will already have ground to a halt by that
>> stage if it has memory allocation problems.)
>

> Why not use a wrapper function that will always do the right
> thing?

Because "the right thing" depends on the situation. Simply aborting the
program is a student's way out. Unfortunately, the only worse "solution"
than aborting the program on malloc failure - i.e. not bothering to test at
all - is also the most common "solution", it seems.

Flash Gordon

unread,
Aug 1, 2006, 3:33:57 AM8/1/06
to
Keith Thompson wrote:
> Flash Gordon <sp...@flash-gordon.me.uk> writes:
> [...]
>> As you know very well we discuss C99, C95, C90 and even pre-ANSI C
>> when appropriate. Why do you object so strongly to people not being
>> told when something is a C99 feature and so not portable to such
>> common implementations as MS VC++?
>
> I think you meant to drop the first "not" in that last sentence;
> "people not being told" should be "people being told".

I'll write a program to write out 1000 time, "Do not post to comp.lang.c
at almost 2AM."

#include <stdio.h>

int main(void)
{
int i;

for (i=0; i<1000; i++)
puts("Do not post to comp.lang.c at almost 2AM.");

return 0;

Chris Torek

unread,
Aug 1, 2006, 5:27:25 AM8/1/06
to
In article <4rydnRzhVqG...@bt.com>
Richard Heathfield <inv...@invalid.invalid> wrote:
>... What did C99 give us? Mixed declarations? Sugar. // comments?
>More sugar.

True, although sometimes a little syntactic sugar helps with
understanding.

>VLAs? More sugar.

Here I have to disagree: when you need VLAs, you really need them.
In particular, they allow you to write matrix algebra of the sort
that Fortran has had for years:

void some_mat_op(int m, int n, double mat[m][n]) {
...
}

In C89 you have to sneak around the standard to do this at all
(assuming you are using actual "array of array"s rather than
"array of pointers to vectors" or "vector of pointers to vector
of pointers", anyway).

>Compound literals - sure, they might come in handy one day.

They missed a bet with them though: a compound literal outside a
function has static duration, but any compound literal within a
function has automatic duration, with no way to give it static
duration. Hence:

int *f(void) {
static int a[] = { 1, 2, 3, 42 };
return a;
}

is OK, but you cannot get rid of the name:

int *f(void) {
return (int []){ 1, 2, 3, 42 };
}

is not, because the anonymous array object vanishes. (You can,
however, make the array "const", provided the function returns
"const int *".) Clearly C99 should have included:

return (static int []){ 1, 2, 3, 42 };

(and the corresponding version with const). :-)

(The syntax for compound literals is rather ugly, although I am
not sure how one could specify them unambiguously otherwise.)

>A colossal math library? Hardly anyone needs it ...

Although again, those who want to write their Fortran code in C
will find it handy. :-)
--
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.

Gernot Frisch

unread,
Aug 1, 2006, 6:06:25 AM8/1/06
to

>>A colossal math library? Hardly anyone needs it ...
>
> Although again, those who want to write their Fortran code in C
> will find it handy. :-)

A "good" programmer can write FORTRAN code in any language ;)


Chris Torek

unread,
Aug 1, 2006, 5:45:29 AM8/1/06
to
>> "Frederick Gotham" <fgot...@SPAM.com> wrote in message
>> news:oPvzg.12108$j7.3...@news.indigo.ie...
>>>Arrays whose length is known at compile time are far more efficient to work
>>>with.

>dco...@connx.com a écrit :


>> I doubt this statement.
>>
>> On stack based machines, it's nothing more than a subtraction. Whether
>> the value is passed in or known at compile time makes no difference.

It depends on a lot of things; sometimes fixed-size arrays really
are more efficient, and sometimes not. In particular, given a
code sequence like:

void f(int n) {
int i, a[N];
... loop i over n items, working with a[i] ...
}

(where n <= N of course), the various a[i]s may be at an "easily
addressed" location like -100(sp)[regI]. Converting this to:

void f(int n) {
int i, a[n];
... loop i over n items ...
}

requires replacing the "pseudo-constant" -100(sp) with a value.
If the function happens to be large enough to exert enough register
pressure to spill important loop variables, this can make a
significant difference. Obviously this depends on (at least) the
target architecture and the number of "live" loop variables.

In article <44ce9005$0$850$ba4a...@news.orange.fr>


jacob navia <ja...@jacob.remcomp.fr> wrote:
>I implemented this by making the array a pointer, that
>gets its value automagically when the function starts by making
>a subtraction from the stack pointer. Essentially
>

>int fn(int n)
>{
> int tab[n];
>...
>}
>
>becomes
>

>int fn(int n)
>{
> int *tab = alloca(n*sizeof(int));
>}
>
>The access is done like any other int *...

As someone else noted, this is not sufficient, because "sizeof tab"
must produce n*sizeof(int), not 1*sizeof(int *).

Morever, one *should* not do this quite so naively. Consider the
following code fragments:

int f(int, int);

void foo(int n) {
for (int i = 0; i < n; i++) {
int siz = f(i, n); // usually n, sometimes not
int arr[siz];

for (int j = 0; j < siz; j++) {
...
}
}
}

int main(void) {
foo(100000);
...
}

The inner (nested) loop runs about 10 billion (10 thousand million,
if you use non-US "billion") times, so this will take a while;
meanwhile the outer loop allocates 1 million times "sizeof(int)"
array elements. If sizeof(int) is 4, this is approximately 4
megabytes, which should easily fit on most desktop computers.

If you naively re-"alloca" the array every trip through the loop,
however, you will need one million of these ~4 MB regions, which
will (since the number is 1 million rather than 1048576) consume
a bit over 37 gigabytes. This is a little bit likely to run out.

The array should be destroyed at the bottom of the loop before
being recreated (with the new size "siz") at the top. (VLAs are
thus very different from alloca(): alloca()ed space is generally
*not* destroyed simply because the block in which it was allocated
has terminated; alloca()d space has "function duration", as it
were.)

Note that on machines with virtual frame pointers (MIPS, x86 with
gcc and -fomit-frame-pointer), a function that uses a VLA forces
the compiler to allocate an actual frame pointer within that
function. VLAs thus also interact with longjmp().

Chris Torek

unread,
Aug 1, 2006, 5:50:20 AM8/1/06
to
[On testing for "printf" failure by using
fflush(stdout);
if (ferror(stdout)) ...
at the end of the program]

In article <gbstc2p82ogn5ift3...@4ax.com>


jaysome <jay...@spamcop.net> wrote:
>Did you have a test case for this code? If so, did you ever achieve
>decision coverage in the case where ferror() gave an error? That would
>be remarkable if you did, and I would like to hear how you did it.

It is not *quite* the same, but the principle is identical: in my
kernel-configuration generation program for BSD/OS (a variant is
found in NetBSD), I check the results of writing to the various
files using code like the above (I get to fclose() them though).
I did in fact test it once, by accident: I had a nearly-full disk
partition, and running "config new-kernel" filled it up so that
the generated configuration was incomplete. The program detected
and reported the error.

Redirecting standard output to a nearly-full disk (or limited-size
file, or using whatever other system resource limits are available)
is probably the easiest way to test this kind of code.

Chris Torek

unread,
Aug 1, 2006, 5:56:35 AM8/1/06
to
In article <ean6p...@news1.newsguy.com> I wrote:
>... you cannot get rid of the name:

>
> int *f(void) {
> return (int []){ 1, 2, 3, 42 };
> }
>
>is not, because the anonymous array object vanishes. (You can,
>however, make the array "const", provided the function returns
>"const int *".)

I realize I phrased this badly (so that the statement as written
is wrong). What I meant is that you can make compound literals
"const", e.g.:

void f(void) {
int *ip = (int []){ 1, 2, 3, 42 };
...
}

or:

void f(void) {
const int *ip = (const int []){ 1, 2, 3, 42 };
...
}

If you make the compound literal "const", the compiler can generate
a single copy, even if it appears multiple times, although no compiler
is forced to work hard to optimize like this:

const int *p1 = (const int[]){ 1, 2 };
const int *p2 = (const int[]){ 1, 2 };

if (p1 == p2)
puts("p1==p2; this is allowed");
else
puts("p1!=p2; this is allowed too");

(this is identical in principle to string-literal sharing).

(It seems to me inconsistent that the objects produced by string
literals always have static duration, while those produced by
compound literals have automatic duration whenever possible.)

Richard Bos

unread,
Aug 1, 2006, 9:09:19 AM8/1/06
to
dco...@connx.com wrote:

> jacob navia wrote:
> > In this group there is a bunch of people that call themselves 'regulars'
> > that insist in something called "portability".
> >

> > Portability for them means the least common denominator.

> I don't understand why anyone would complain against standards.

Because weaning programmers off the Standard means you can shift more of
your own embrace-and-extend crap. As simple as that, IYAM.

Richard

Andrew Poelstra

unread,
Aug 1, 2006, 10:14:33 AM8/1/06
to

It would've been interesting had any of the clc regs been there while
that class was being taught.

--
Andrew Poelstra <website down>
To reach my email, use <email also down>
New server ETA: 42

Clever Monkey

unread,
Aug 1, 2006, 11:22:10 AM8/1/06
to
jacob navia wrote:
> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".
>
> Portability for them means the least common denominator.
>
This is an unlikely definition. Try something like "most conforming to
a standard" or "least depending on undefined behaviour". This is the
mantra I hear over and over in c.l.c.

> Write your code so that it will compile in all old and broken
> compilers, preferably in such a fashion that it can be moved with no
> effort from the embedded system in the coffe machine to the 64 bit
> processor in your desktop.
>
Unless, of course, you know you are unlikely to deploy your app on the
CoffeeMaster 3000.

> Sure, you can do that. But as you know, there is no free lunch.
> You pay for that "portability" by missing all the progress done
> since 1989 in C.
>

Unless, of course, you only cared about the C99 standard, in which case
you would miss out on all the progress since then. Life is unfair.

> Note that there is objectively speaking not a single useful
> program in C that can be ported to all machines that run the
> language.
>
No one who knows what they are saying ever suggested otherwise, I'm
pretty sure. A portable, comforming program will be easy to port to a
new platform. The operating system world is full of examples of code
written with portability in mind. Usually the biggest problems run into
are compiler inconsistencies.

Portability doesn't mean no work; it means less work for a particular
development need. It is about paying a development cost up front to
lessen the maintenance costs down the line. One decides how much
portability they need depending on the task and target platforms.

Like many things in life, it is a trade-off.

Well, it looks like you are really just spoiling for a fight. Based on
this thread so far, it looks like you got one.

Clever Monkey

unread,
Aug 1, 2006, 11:46:53 AM8/1/06
to
jacob navia wrote:
> Keith Thompson a écrit :
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>
>>> Frederick Gotham a écrit :
>>>
>>>>> Sure, you can do that. But as you know, there is no free lunch.
>>>>> You pay for that "portability" by missing all the progress done
>>>>> since 1989 in C.
>>
>>
>> Or you pay for a few C99-specific features by losing a significant
>> degree of portability.
>
> Well but this group is about STANDARD C or not?
>
Yes.

> If we do not agree about what standard C is, we can use the standard.
>

Which standard? One can debate the pros and cons of any sort of
standardization, or the value of one standard that is meant to supersede
another. A standard is a standard, however, and is best discussed
within context.

> But if we do not even agree what standard C is ther can't be
> any kind of consensus in this group you see?
>

Once we decide which of the major standards we are discussing, then you
will get consensus. Additionally, one can compare and contrast standards.

> The talk about "Standard C" then, is just hollow words!!!
>

You seem to have an idee fixe that because there is more than one
standard, this means that there is no standard. Each standard is
constructed to take previous standards into consideration. As discussed
elsewhere, it is up to the developer to understand how these standards
affect the code he or she may write, and decide how "standard", which
"standard" and how much "portability" is required.

It. Is. A. Trade-off.

Why worry so much? Any legacy language of sufficient vintage has a long
history that includes many de facto or official standards. I work on an
application that has been ported to many different platforms over the
decades, from early Win16 systems through to 64-bit Windows, P390s, a
variety of real Unixes and everything in-between.

While our code is not instantly portable, the work to port to such a
diverse set of platforms is controlled via a core set of libraries (we
call them "quickports", and they have that name for a reason). This is
where grungy platform details can be wrapped by (wait for it) in a
standard interface. I assume this is how most shops do this sort of
thing, since it is the way I've always done it.

Like any collection of code of a certain age we do rely on a little
preprocessor magic, usually to work around non-conforming compilers and
the majority of the GUI stuff has been re-done in Java. The core C code
is as portable and conforming as we need it to be. Without a language
standard we would be writing to the compilers notion of an ad hoc
standard anyway.

Let me repeat this, in case you missed it: even if there were no
official or de facto standard, each compiling system and platform would
end up dreaming up its own ad hoc standard, anyway. Why not codify
existing good practice and put constraints around edge cases? This is
generally considered a Good Thing.

The notion that we would all just target a single platform using a
single compiler that eschews standards because it knows better (and why
*not* go off into an "obvious" better direction, since you will *never*
need to run on any other platform anyway) rings pretty freaking hollow
to me.

Ben Pfaff

unread,
Aug 1, 2006, 11:41:36 AM8/1/06
to
"Old Wolf" <old...@inspire.net.nz> writes:

> That reminds me of the course where I learned C. The tutor advised:
>
> #define MALLOC(type, n) ((type *)malloc((n) * sizeof(type))

Well, at least this kind of macro always casts to the right type,
unlike manual casts.
--
"I don't have C&V for that handy, but I've got Dan Pop."
--E. Gibbons

Ben Pfaff

unread,
Aug 1, 2006, 11:43:05 AM8/1/06
to
jaysome <jay...@spamcop.net> writes:

You can test it with system-specific features, e.g. /dev/full. I
don't recall whether I did so, though.

Ben Pfaff

unread,
Aug 1, 2006, 11:44:04 AM8/1/06
to
Richard Heathfield <inv...@invalid.invalid> writes:

> Ben Pfaff said:
>
>> Frederick Gotham <fgot...@SPAM.com> writes:
>>
>>> For instance, if I were allocating upwards of a megabyte of memory, I
>>> would probably take precautions:
>>>
>>> int *const p = malloc(8388608 / CHAR_BIT
>>> + !!(8388608 % CHAR_BIT));
>>>
>>> if(!p) SOS();
>>>
>>> But if I'm allocating less than a kilobytes... I probably won't bother
>>> most of the time. (The system will already have ground to a halt by that
>>> stage if it has memory allocation problems.)
>>
>> Why not use a wrapper function that will always do the right
>> thing?
>
> Because "the right thing" depends on the situation. Simply aborting the
> program is a student's way out. Unfortunately, the only worse "solution"
> than aborting the program on malloc failure - i.e. not bothering to test at
> all - is also the most common "solution", it seems.

I consider calling exit(EXIT_FAILURE) strictly better than
undefined behavior due to dereferencing a null pointer.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}

Al Balmer

unread,
Aug 1, 2006, 12:00:02 PM8/1/06
to
On 31 Jul 2006 18:34:34 -0700, dco...@connx.com wrote:

> I can easily imagine legal problems for a C compiler vendor
>who claimed in their advertizing that their compiler adhered to the
>ANSI/ISO C standard but in fact, failed badly on many measures.

But this has nothing to do with the legal status of the standard. it
has to do with the claim. It's exactly the same as a car dealer
selling me an eight-cylinder car which turns out to have only six
cylinders. The dealer is at risk of both legal and civil action, but
not because eight cylinder cars are standard.

--
Al Balmer
Sun City, AZ

Kenneth Brody

unread,
Aug 1, 2006, 11:57:15 AM8/1/06
to
jacob navia wrote:
>
> Richard Heathfield a écrit :
[... C99 ...]
> > Mixed declarations? Sugar.

> // comments? More sugar. VLAs? More sugar.
>
> And what do you have against sugar?
> You drink your coffee without it?

Many people don't like sugar in their coffee.

> I mean, C is just syntatic sugar for assembly language. Why
> not program in assembly then?

Portability. :-)

[...]


> VLAs are a more substantial step since it allows to allocate precisely
> the memory the program needs without having to over-allocate or risk
> under allocating arrays.
>

> Under C89 you have to either:
> 1) allocate memory with malloc

> 2) Decide a maximum size and declare a local array of that size.
>

> Both solutions aren't specially good. The first one implies using malloc
> with all associated hassle,

What "hassle"?

Oh, no! I have to remember to free it! However shall I handle the
pressure? :-)

> and the second risks allocating not enough
> memory. C99 allows you to precisely allocate what you need and no more.

Yet, as I understand it, if the VLA can't be allocated, the result
is undefined behavior. With malloc/free, you have well-defined
behavior for failure. True, you have to check for failure, but at
least you _can_ check for failure, unlike VLAs.

[...]


> > The real progress has been in the development of third-party libraries, many
> > of which are at least a bit cross-platform.
>
> That is a progress too, but (I do not know why) we never discuss them
> in this group.

Because they're not part of C itself.

> Maybe what frustrates me is that all this talk about "Stay in C89, C99
> is not portable" is that it has taken me years of effort to implement

> (and not all of it) C99 and that not even in this group, where we should


> promote standard C C99 is accepted as what it is, the current standard.

C99 is portable to systems which have C99 compilers.

AFAIK, C99 questions are not off-topic here, even if people will
point out that it's C99. (Of course, I may be wrong.)

> I mean, each one of us has a picture of what C "should be". But if we
> are going to get into *some* kind of consensus it must be the published
> standard of the language, whether we like it or not.

Umm... Isn't that what we do here?

> For instance the fact that main() returns zero even if the programmer
> doesn't specify it I find that an abomination. But I implemented that
> because it is the standard even if I do not like it at all.

That was probably a concession to not break formerly "working"
programs which weren't really "right" to begin with.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsA...@gmail.com>


Kenneth Brody

unread,
Aug 1, 2006, 12:02:27 PM8/1/06
to

A "great" programmer can even write it in FORTRAN.

Thomas Carter

unread,
Aug 1, 2006, 12:18:02 PM8/1/06
to
On Mon, 31 Jul 2006 23:30:45 +0200, jacob navia wrote:

> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".
>
> Portability for them means the least common denominator.

I am not sure about that - somewhere I read that a program is said to be
portable if the amount of work involved in compiling it for a platform
different than the one it was developed under is less than teh work
necessary to develop it from scratch for the new platform.


Richard Heathfield

unread,
Aug 1, 2006, 12:27:47 PM8/1/06
to
Ben Pfaff said:

> Richard Heathfield <inv...@invalid.invalid> writes:
>

<snip>

>> Simply aborting the
>> program is a student's way out. Unfortunately, the only worse "solution"
>> than aborting the program on malloc failure - i.e. not bothering to test
>> at all - is also the most common "solution", it seems.
>
> I consider calling exit(EXIT_FAILURE) strictly better than
> undefined behavior due to dereferencing a null pointer.

I agree entirely. Perhaps you misread my reply?

Kenneth Brody

unread,
Aug 1, 2006, 12:16:29 PM8/1/06
to
Flash Gordon wrote:
>
> Keith Thompson wrote:
[...]

> > I think you meant to drop the first "not" in that last sentence;
> > "people not being told" should be "people being told".
>
> I'll write a program to write out 1000 time, "Do not post to comp.lang.c
> at almost 2AM."
>
> #include <stdio.h>
>
> int main(void)
> {
> int i;
>
> for (i=0; i<1000; i++)
> puts("Do not post to comp.lang.c at almost 2AM.");
>
> return 0;
> }

Nor should you post at 3:30AM.

No terminating newline in your output.

Kenneth Brody

unread,
Aug 1, 2006, 12:28:31 PM8/1/06
to
jacob navia wrote:
[...]
> 1) VLAs allow you to precisely allocate the memory the program needs
> instead of using malloc (with all its associated problems) or having
> to decide a maximum size for your local array, allocating too much
> for most cases.

>
> int fn(int n)
> {
> int tab[n];
> }
>
> allocates JUST what you need AT EACH CALL.
[...]

You've mentioned the "hassle" and "problems" of using malloc, yet I
don't see any description of what you mean by that.

Also, how do you handle the fact that failure to allocate a VLA for
whatever reason invokes UB?

Kenneth Brody

unread,
Aug 1, 2006, 12:53:38 PM8/1/06
to
dco...@connx.com wrote:
>
> Keith Thompson wrote:
[...]
> > > dco...@connx.com a écrit :
> > >> C99 is standard C. Other standards must be prefaced by the name of
> > >> the standard (IMO-YMMV). That's because C99 legally replaces the
> > >> previous C standard.
[...]
> > First, I disagree with the use of the term "legally". ISO is not a
> > governmental body, and the C standard does not have the force of law.
> > Nobody is going to arrest a user or an implementer for failing to
> > conform to it.
>
> ANSI is connected to the U.S. government and (along with NIST) is used
> to establish standards in the United States. While standard adoption
> is 'voluntary' there can still be legal ramifications. For instance,
> if I stamp the head of my bolt with a certain number of diamond shapes
> on it, that is a claim of adherence to a standard. If the claim is
> false, the manufacturer could get sued, possibly go to jail, etc.
> Sometimes, formal standards do get adopted with more or less legal
> weight, which would vary from country to country and standard to
> standard. I can easily imagine legal problems for a C compiler vendor

> who claimed in their advertizing that their compiler adhered to the
> ANSI/ISO C standard but in fact, failed badly on many measures.

But there is nothing "illegal" about not following these standards.
The "illegal" part is claiming conformance when you don't, but that's
no different than my claiming to sell "half-gallon" containers of
ice cream and only putting 63 ounces in them. There's nothing illegal
about selling 63-ounce containers of ice cream. (Now, there may be
segments of society/business/whatever, where the law says you must
follow a given standard, but that's not the case here.)

[...]

Kenneth Brody

unread,
Aug 1, 2006, 1:07:26 PM8/1/06
to
Tom St Denis wrote:
[...]
> No one expects a 3D video game to work on an 8051.

Well, no "reasonable" person, anyway. :-)

> On the otherhand, one would expect some non-interface type routine to
> work anywhere.
>
> My own math lib [LibTomMath] has been built on things as low as an 8086
> with TurboC all the way up through the various 64-bit servers and
> consoles. Without sacrificing too much speed or ANY functionality.
>
> Similarly my crypto code is used pretty much anywhere without hacking
> for this compiler, that compiler, etc.

Oh, you're _that_ Tom?

I can vouch for LibTomCrypt's "portability" to the extent that I have
used it in our program, which runs on Windows, Unix, Linux, and several
others, on numerous hardware platforms.

Richard Heathfield

unread,
Aug 1, 2006, 1:35:04 PM8/1/06
to
Kenneth Brody said:

> Flash Gordon wrote:
>>
>> Keith Thompson wrote:
> [...]
>> > I think you meant to drop the first "not" in that last sentence;
>> > "people not being told" should be "people being told".
>>
>> I'll write a program to write out 1000 time, "Do not post to comp.lang.c
>> at almost 2AM."
>>
>> #include <stdio.h>
>>
>> int main(void)
>> {
>> int i;
>>
>> for (i=0; i<1000; i++)
>> puts("Do not post to comp.lang.c at almost 2AM.");
>>
>> return 0;
>> }
>
> Nor should you post at 3:30AM.
>
> No terminating newline in your output.

You shouldn't post at 4:16pm. He used puts(), not printf().

Walter Roberson

unread,
Aug 1, 2006, 1:35:29 PM8/1/06
to
In article <44CF7E5D...@spamcop.net>,
Kenneth Brody <kenb...@spamcop.net> wrote:
>Flash Gordon wrote:

>> puts("Do not post to comp.lang.c at almost 2AM.");

>Nor should you post at 3:30AM.

>No terminating newline in your output.

puts() automatically adds newline.
--
Prototypes are supertypes of their clones. -- maplesoft

jacob navia

unread,
Aug 1, 2006, 1:37:04 PM8/1/06
to
Kenneth Brody wrote:
> jacob navia wrote:
> [...]
>
>>1) VLAs allow you to precisely allocate the memory the program needs
>>instead of using malloc (with all its associated problems) or having
>>to decide a maximum size for your local array, allocating too much
>>for most cases.
>>
>>int fn(int n)
>>{
>> int tab[n];
>>}
>>
>>allocates JUST what you need AT EACH CALL.
>
> [...]
>
> You've mentioned the "hassle" and "problems" of using malloc, yet I
> don't see any description of what you mean by that.
>
> Also, how do you handle the fact that failure to allocate a VLA for
> whatever reason invokes UB?
>
malloc and friends rely on you freeing the memory.

They need a potentially expensive call to get the memory
since malloc must go through the free list looking for a right
sized block.

All this is avoided with VLAs. No need to free the block,
and no expensive looking up of the free list to see if the block
can be coalesced into a larger block to avoid memory fragmentation,
etc.

jacob navia

unread,
Aug 1, 2006, 1:50:03 PM8/1/06
to
Walter Roberson wrote:
> In article <44CF7E5D...@spamcop.net>,
> Kenneth Brody <kenb...@spamcop.net> wrote:
>
>>Flash Gordon wrote:
>
>
>>> puts("Do not post to comp.lang.c at almost 2AM.");
>
>
>>Nor should you post at 3:30AM.
>
>
>>No terminating newline in your output.
>
>
> puts() automatically adds newline.

You are cheating since you posted at 19:35...

:-)

Tom St Denis

unread,
Aug 1, 2006, 1:50:58 PM8/1/06
to
jacob navia wrote:
> malloc and friends rely on you freeing the memory.

Yeah, oddly enough malloc and STACKS solve different problems. You
halfwit malcontent.


ooh, ooh next you'll point out that memset is the faster qsort()!!!

> All this is avoided with VLAs. No need to free the block,
> and no expensive looking up of the free list to see if the block
> can be coalesced into a larger block to avoid memory fragmentation,
> etc.

Yeah except you can't free VLAs [or alloca's] in random order.

Tom

Skarmander

unread,
Aug 1, 2006, 2:31:30 PM8/1/06
to
John Bode wrote:
> jacob navia wrote:
>> In this group there is a bunch of people that call themselves 'regulars'
>> that insist in something called "portability".
>>
>> Portability for them means the least common denominator.
>
> It primarily means that conforming compilers have been implemented on a
> wide variety of hardware and OS combinations, so that conforming code
> on one platform can be expected to behave the same on any other
> platform.
>
> Secondarily, it means structuring your code so that it supports
> multiple platforms concurrently with minimal effort, which I've had to
> do on numerous occasions (the most painful being classic MacOS,
> Solaris, and Windows 3.1).
>
> And as far as supporting the "least common denominator", it's not my
> fault that Microsoft went out of its way to make it nigh impossible to
> code for Windows and *anything else* by "extending" C to such a
> ridiculous degree. Nor is it my fault that the bulk of the lossage was
> on the Windows side.
>
It's not exactly "nigh impossible" in a technical sense; it's just that if
you choose the path of least resistance (that is, you code as Microsoft
recommends) you've already lost, and practically consigned your program to
single-platform hell for all eternity. (Alright, so the various flavors of
Windows technically constitute different platforms, but you know what I mean.)

It's very true that you are much better off aiming for a portable program
that runs on Win32 than a Win32 program that's portable. If you drink the
Kool-Aid and litter your program with BOOL, LPSTR and UINT because that's
what the Windows-specific parts of it use, you lose. Portability for Windows
is a delicate topic, for which the documentation of the natives offers you
little to no help.

S.

Skarmander

unread,
Aug 1, 2006, 2:33:13 PM8/1/06
to
Point in case: the rest of my post used "Win32" where Win16/32/64 would have
done just as well (or perhaps even better, since the problems you'll have
porting between even these platforms are illustrative).

S.

Ben Pfaff

unread,
Aug 1, 2006, 2:33:54 PM8/1/06
to
Richard Heathfield <inv...@invalid.invalid> writes:

> Ben Pfaff said:
>
>> Richard Heathfield <inv...@invalid.invalid> writes:
>>> Simply aborting the
>>> program is a student's way out. Unfortunately, the only worse "solution"
>>> than aborting the program on malloc failure - i.e. not bothering to test
>>> at all - is also the most common "solution", it seems.
>>
>> I consider calling exit(EXIT_FAILURE) strictly better than
>> undefined behavior due to dereferencing a null pointer.
>
> I agree entirely. Perhaps you misread my reply?

My goal was not really to correct you, but to make my own
position clear.

Andrew Poelstra

unread,
Aug 1, 2006, 3:29:26 PM8/1/06
to
On 2006-08-01, Ben Pfaff <b...@cs.stanford.edu> wrote:
> "Old Wolf" <old...@inspire.net.nz> writes:
>
>> That reminds me of the course where I learned C. The tutor advised:
>>
>> #define MALLOC(type, n) ((type *)malloc((n) * sizeof(type))
>
> Well, at least this kind of macro always casts to the right type,
> unlike manual casts.

Possibly. You can still do
long *x = MALLOC (short, 15);
although in that case you should get a diagnostic.

Hmm. It seems this is superior to a manual malloc (s * sizeof(type)),
but of course using

p = malloc (n * sizeof *p);

is superior to both.


(Not suggesting that you didn't know that; I'm merely commenting that
the macro is a reasonable(?) solution that shouldn't necessarily be
thrown out.)

Flash Gordon

unread,
Aug 1, 2006, 4:10:44 PM8/1/06
to
Richard Heathfield wrote:
> Kenneth Brody said:
>
>> Flash Gordon wrote:
>>> Keith Thompson wrote:
>> [...]
>>>> I think you meant to drop the first "not" in that last sentence;
>>>> "people not being told" should be "people being told".
>>> I'll write a program to write out 1000 time, "Do not post to comp.lang.c
>>> at almost 2AM."
>>>
>>> #include <stdio.h>
>>>
>>> int main(void)
>>> {
>>> int i;
>>>
>>> for (i=0; i<1000; i++)
>>> puts("Do not post to comp.lang.c at almost 2AM.");
>>>
>>> return 0;
>>> }
>> Nor should you post at 3:30AM.
>>
>> No terminating newline in your output.
>
> You shouldn't post at 4:16pm. He used puts(), not printf().

What is worse, I did it maliciously and with forethought ;-)

In any case, I posted it at 8:33AM. Aren't time zones wonderful?
--
Flash Gordon
Still sigless on this computer.

Keith Thompson

unread,
Aug 1, 2006, 5:25:04 PM8/1/06
to
Kenneth Brody <kenb...@spamcop.net> writes:
> jacob navia wrote:
[...]

>> Maybe what frustrates me is that all this talk about "Stay in C89, C99
>> is not portable" is that it has taken me years of effort to implement
>> (and not all of it) C99 and that not even in this group, where we should
>> promote standard C C99 is accepted as what it is, the current standard.
>
> C99 is portable to systems which have C99 compilers.
>
> AFAIK, C99 questions are not off-topic here, even if people will
> point out that it's C99. (Of course, I may be wrong.)

C99 questions are certainly topical here, and we discuss them all the
time. (We also point out that using C99-specific features can lead to
portability problems, and sometimes we suggest C90 alternatives.)

[...]

>> For instance the fact that main() returns zero even if the programmer
>> doesn't specify it I find that an abomination. But I implemented that
>> because it is the standard even if I do not like it at all.
>
> That was probably a concession to not break formerly "working"
> programs which weren't really "right" to begin with.

Such programs "worked" only on some platforms. On many systems,
falling off the end of main() would return a failure indication; for
example, on Solaris it would do the equivalent of exit(1).

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Keith Thompson

unread,
Aug 1, 2006, 5:31:24 PM8/1/06
to
jacob navia <ja...@jacob.remcomp.fr> writes:
[...]

> malloc and friends rely on you freeing the memory.
>
> They need a potentially expensive call to get the memory
> since malloc must go through the free list looking for a right
> sized block.
>
> All this is avoided with VLAs. No need to free the block,
> and no expensive looking up of the free list to see if the block
> can be coalesced into a larger block to avoid memory fragmentation,
> etc.

And no possibility of catching errors.

A conforming implementation could simply ignore an allocation error
for a VLA, allowing the program to continue attempting to access it,
possibly stepping on other variables or system data structures.

But it's more likely that a stack overflow will immediately abort the
program (and not allow any opportunity for cleanup).

It's true that the same consideration applies to ordinary automatic
variables, particularly with deep recursion, but VLAs are more likely
to cause problems.

The bad (i.e., mildly inconvenient) thing about malloc and friends is
that they require to to manage memory allocation yourself. The good
(i.e., vital) think about malloc and friends is that they *allow* you
to manager memory allocation yourself.

jacob navia

unread,
Aug 1, 2006, 5:36:45 PM8/1/06
to
Keith Thompson wrote:
> jacob navia <ja...@jacob.remcomp.fr> writes:
> [...]
>
>>malloc and friends rely on you freeing the memory.
>>
>>They need a potentially expensive call to get the memory
>>since malloc must go through the free list looking for a right
>>sized block.
>>
>>All this is avoided with VLAs. No need to free the block,
>>and no expensive looking up of the free list to see if the block
>>can be coalesced into a larger block to avoid memory fragmentation,
>>etc.
>
>
> And no possibility of catching errors.

It depends, my implementation allows to catch the equivalent
of SIGSTACKOVFL, i.e. you can have a try/catch block around this
and catch the stack overflow. The handler must be specially written,
and I describe this in the tutorial of lcc-win32. Obviously this is
a non portable solution.

Keith Thompson

unread,
Aug 1, 2006, 6:16:09 PM8/1/06
to

By contrast, allocation errors can be caught using 100% portable code
if you use malloc() instead.

Peter Nilsson

unread,
Aug 1, 2006, 6:38:14 PM8/1/06
to
Keith Thompson wrote:
> jacob navia <ja...@jacob.remcomp.fr> writes:
> > Keith Thompson wrote:
> > > jacob navia <ja...@jacob.remcomp.fr> writes:
> > > > malloc and friends rely on you freeing the memory.
> > > >
> > > > They need a potentially expensive call to get the memory
> > > > since malloc must go through the free list looking for a right
> > > > sized block.
> > > >
> > > > All this is avoided with VLAs. No need to free the block,
> > > > and no expensive looking up of the free list to see if the block
> > > > can be coalesced into a larger block to avoid memory
> > > > fragmentation, etc.
> > >
> > > And no possibility of catching errors.
> >
> > It depends, my implementation allows to catch the equivalent
> > of SIGSTACKOVFL, i.e. you can have a try/catch block around this
> > and catch the stack overflow. The handler must be specially written,
> > and I describe this in the tutorial of lcc-win32. Obviously this is
> > a non portable solution.
>
> By contrast, allocation errors can be caught using 100% portable code
> if you use malloc() instead.

That's not strictly true. On platforms with lazy allocation schemes,
malloc
may _never_ return a null pointer, but the program can still crash with
(say) an unspecified signal being raised.

Fact is, in C you _never_ have a guarantee over the allocation of
automatic storage. And the 'guarantee' for dynamic storage is only
truly applicable to the virtual C machine.

Note that VLAs are not optional for conforming freestanding C99
implementations, but malloc and friends are.

I tend to try and limit automatic allocations to less than 256 bytes.
VLAs don't preclude such measures. The handling would be no
different to the handling of malloc.

--
Peter

Dik T. Winter

unread,
Aug 1, 2006, 7:39:46 PM8/1/06
to
In article <ean6p...@news1.newsguy.com> Chris Torek <nos...@torek.net> writes:
> In article <4rydnRzhVqG...@bt.com>
> Richard Heathfield <inv...@invalid.invalid> wrote:
...
> >VLAs? More sugar.
>
> Here I have to disagree: when you need VLAs, you really need them.
> In particular, they allow you to write matrix algebra of the sort
> that Fortran has had for years:
>
> void some_mat_op(int m, int n, double mat[m][n]) {
> ...
> }

This is something different. You are dimensioning the arguments here.
What it solves is problems like:
void some_mat_op(int m, int n, double mat[m][n]) {
double temp[m][n];
...
}
something that Fortran has only since 1990. It was in Algol 60 from
the very beginning.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Keith Thompson

unread,
Aug 1, 2006, 7:47:05 PM8/1/06
to
"Peter Nilsson" <ai...@acay.com.au> writes:
> Keith Thompson wrote:
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>> > Keith Thompson wrote:
>> > > jacob navia <ja...@jacob.remcomp.fr> writes:
>> > > > malloc and friends rely on you freeing the memory.
>> > > >
>> > > > They need a potentially expensive call to get the memory
>> > > > since malloc must go through the free list looking for a right
>> > > > sized block.
>> > > >
>> > > > All this is avoided with VLAs. No need to free the block,
>> > > > and no expensive looking up of the free list to see if the block
>> > > > can be coalesced into a larger block to avoid memory
>> > > > fragmentation, etc.
>> > >
>> > > And no possibility of catching errors.
>> >
>> > It depends, my implementation allows to catch the equivalent
>> > of SIGSTACKOVFL, i.e. you can have a try/catch block around this
>> > and catch the stack overflow. The handler must be specially written,
>> > and I describe this in the tutorial of lcc-win32. Obviously this is
>> > a non portable solution.
>>
>> By contrast, allocation errors can be caught using 100% portable code
>> if you use malloc() instead.
>
> That's not strictly true. On platforms with lazy allocation schemes,
> malloc may _never_ return a null pointer, but the program can still
> crash with (say) an unspecified signal being raised.

Good point; I forgot about lazy allocation schemes.

In my opinion, such schemes violate the C standard, but I suppose
we're stuck with them.

One workaround is to initialize the allocated object after malloc()
succeeds, but (a) that can be expensive, and (b) a failure to
initialize it can't be caught anyway.

On an OS that does lazy allocation, it should still be possible to
provide a routine that does non-lazy allocation, ensuring that the
supposedly allocated memory really is allocated, and harmlessly
deallocating the memory and returning an error code if it isn't. (I
suggest using a null pointer as the error code, and calling the
routine "malloc".)

> Fact is, in C you _never_ have a guarantee over the allocation of
> automatic storage. And the 'guarantee' for dynamic storage is only
> truly applicable to the virtual C machine.
>
> Note that VLAs are not optional for conforming freestanding C99
> implementations, but malloc and friends are.

True. We tend to assume hosted implementations here. I wouldn't want
to require every article here to explicitly note the difference, but
we should probably mention it more often than we do.

> I tend to try and limit automatic allocations to less than 256 bytes.
> VLAs don't preclude such measures. The handling would be no
> different to the handling of malloc.

malloc at least has a mechanism for reporting an allocation failure
without killing the caller. VLAs don't (at least not portably).

Dik T. Winter

unread,
Aug 1, 2006, 8:54:11 PM8/1/06
to
In article <lnbqr42...@nuthaus.mib.org> Keith Thompson <ks...@mib.org> writes:
> "Peter Nilsson" <ai...@acay.com.au> writes:
...

> > That's not strictly true. On platforms with lazy allocation schemes,
> > malloc may _never_ return a null pointer, but the program can still
> > crash with (say) an unspecified signal being raised.
>
> Good point; I forgot about lazy allocation schemes.
>
> In my opinion, such schemes violate the C standard, but I suppose
> we're stuck with them.

I think to, and they also violate quite a few other things. In the
OS's that came with lazy allocation schemes we have always shut it off.
It can lead to problems later on that can be very serious. (When did
that daemon die, and why?)

> On an OS that does lazy allocation, it should still be possible to
> provide a routine that does non-lazy allocation, ensuring that the
> supposedly allocated memory really is allocated, and harmlessly
> deallocating the memory and returning an error code if it isn't.

It should be, but in general isn't. Because the lazy allocation is
done by the system itself, not by the C runtime, or what you want to
call it. I have worked with one such system (SGI IRIX) and it was
horrible. It could happen that your X server was shut down because
of overallocation of memory or that some other random process got
killed.

> > I tend to try and limit automatic allocations to less than 256 bytes.
> > VLAs don't preclude such measures. The handling would be no
> > different to the handling of malloc.
>
> malloc at least has a mechanism for reporting an allocation failure
> without killing the caller. VLAs don't (at least not portably).

With numerical algorithms that use VLA's, you will frequently see that
the allocation with VLA's largely exceeds the 256 bytes. Consider an
algorithm that has as input a matrix and that needs temporary storage
of the same size. Suppose the input matrix (of doubles) is 100x100
(not uncommon), you need temporary storage for 80,000 bytes. Some
numerical algorithms need large amounts of temporary storage, and I
would rather trust malloc in that case.

Herbert Rosenau

unread,
Aug 2, 2006, 1:17:48 AM8/2/06
to
On Mon, 31 Jul 2006 21:30:45 UTC, jacob navia <ja...@jacob.remcomp.fr>
wrote:

> In this group there is a bunch of people that call themselves 'regulars'
> that insist in something called "portability".

Jacob Navia means: there is a twit in the group who means that there
is ony one OS and ony one crappy compiler and portability is nothing
worth.

This group is for the klanguage named C, not for something the twit
means that C shoulb be.

Jacob navia should piss off this group and go spamming for his pissy
thing soewhere as Jacob Naia will never learn for what portability is
made and how that will save money as he is too braindead to accept
that programming is not only a hobby but to make processes more
simple, to save money by writing programs once instead to fiddle
around weith lots of different mashines under different opeating
systems using different compilers.

Programs are not only written once but maintained over a long, really
long livetime where not only compilers going out of maintenance but
the current hardware gets out of lifetime, OSes and compilers change
theyr behavior by changing from version to version or even the need to
change the underlying operating system completely, by chaning from 8
to 16 to 62 to 64.... bit wide words and so on.

Having a language like C that guarantees its behavior by a standard
makes it possible to write programs even in worst case widenly
standard conforming reduces costs.

Only twits like Jacob Navia are whining that the standard hinders them
to get things right. Programmers with a bit working brain knows how to
write portable programs. They know what to do even when this is
partially impossible.

But at least this group is defined to help to write standard
conforming C programs and not to write something a twit means that it
should be C even as it is not.


Jacob Navia piss off this group, it is not designed for you but for
people who need help to get portable programs working.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!

Herbert Rosenau

unread,
Aug 2, 2006, 1:17:48 AM8/2/06
to
On Mon, 31 Jul 2006 22:16:50 UTC, jacob navia <ja...@jacob.remcomp.fr>
wrote:

> Richard Heathfield a écrit :
> > There isn't all that much progress in C. What did C99 give us?
>
> True, C99 didn't really advance the language that much, but it has some
> good points. Anyway, if we are going to stick to standard C, let's agree
> that standard C is Standard C as defined by the standards comitee.
>
> > Mixed declarations? Sugar.
> // comments? More sugar. VLAs? More sugar.
>
> And what do you have against sugar?
> You drink your coffee without it?

If the coffee is really excellent then the answer is simply: yes.

> I mean, C is just syntatic sugar for assembly language. Why
> not program in assembly then?

That is because jacob Navia is too dumb to understund why there is a
standard and what standard conforming programming really means.

> Mixed declarations are a progress in the sense that they put the
> declaration nearer the usage of the variable, what makes reading
> the code much easier, specially in big functions.
>
> True, big functions are surely not a bright idea, but they happen :-)

Really? May be, but written only by idiots who have no idea of program
design.

> I accept that this is not a revolution, or a really big progress in C
> but it is a small step, what is not bad.
>
> VLAs are a more substantial step since it allows to allocate precisely
> the memory the program needs without having to over-allocate or risk
> under allocating arrays.

Jacob Navia should learn how program design works in contrast to
blindly hack around. In 30 years programming in C I've never had a
need for VLAs even as in most of the programs I've written most of the
data I had to handle was in unknown size from some KB up to some
hundret MB in size. In any case an array was always worst case and to
avoid by design.

> Under C89 you have to either:
> 1) allocate memory with malloc
> 2) Decide a maximum size and declare a local array of that size.

What will you say? When you knows how malloc work then it is the best
solution to get data handled when you need semirandom access. When you
have linear access you does not even need an single array.

Learn how to design a program right and you have no problem to handle
some GB on data - even with only some KB memory available. True is you
must be a real programmer, not a braindead hacker to get it right.

> Both solutions aren't specially good. The first one implies using malloc
> with all associated hassle, and the second risks allocating not enough
> memory. C99 allows you to precisely allocate what you need and no more.

Bullshit, pure bullshit that shows only that Jacob Navia is unable to
program right.
In no ways will an VLA able to get thing right you have to handle
reals mass data at once.
Learn to handle malloc(), realloc() and free right, learn which of the
endless long list of tree types helps you to get your data handy by
using a minimum of memory by minimising the time to access it for your
needs.

> > Compound literals - sure, they might come in handy one day.
>
> They do come handy, but again, they are not such a huge progress.
> > A colossal math library?
> > Hardly anyone needs it, and those who do are probably using something like
> > Matlab anyway.
> >
>
> Maybe, maybe not, I have no data concerning this. In any case it
> promotes portability (yes, I am not that stupid! :-) since it
> defines a common interface for many math functions. Besides the control
> you get from the abstracted FPU is very fine tuned.



> You can portably set the rounding mode, for instance, and many other
> things. In this sense the math library is quite a big step from C99.
>
> > The real progress has been in the development of third-party libraries, many
> > of which are at least a bit cross-platform.
>
> That is a progress too, but (I do not know why) we never discuss them
> in this group.

Why should we? This group is for standard C, not for a single specific
CPU or FPU. There are more different and incompatible FPUs as the twit
Jacob navia will ever drem of. Standard C will help you simply to hide
the internals and a halfways good compiler will give you the best that
is possible on each of them.


> Maybe what frustrates me is that all this talk about "Stay in C89, C99
> is not portable" is that it has taken me years of effort to implement
> (and not all of it) C99 and that not even in this group, where we should
> promote standard C C99 is accepted as what it is, the current standard.

Stop spamming for your crap. There are reasons enough to stay on C89.
They are named too often here to repeat them again.

Here in this group is nobody who forces you not to use a C99 compiler
when you have one who is 100% compilant for all the environments you
needs to program for.

> I mean, each one of us has a picture of what C "should be". But if we
> are going to get into *some* kind of consensus it must be the published
> standard of the language, whether we like it or not.

Why is Jacob Navia unable to follow his own words? I'm able to write
100% conforming C89 programs as proven already but I would be unable
to to so for C99 because there is no compiler available for all
different environments I have to write for. So I'm bounded to C89.



> For instance the fact that main() returns zero even if the programmer
> doesn't specify it I find that an abomination. But I implemented that
> because it is the standard even if I do not like it at all.

Boah, ey! That will at least not help to trust it because its
developer is proven as twit already.

Kenneth Brody

unread,
Aug 2, 2006, 11:18:37 AM8/2/06
to
jacob navia wrote:
>
> Keith Thompson wrote:
> > jacob navia <ja...@jacob.remcomp.fr> writes:
[... VLAs being "better" than malloc/free ...]

> >
> > And no possibility of catching errors.
>
> It depends, my implementation allows to catch the equivalent
> of SIGSTACKOVFL, i.e. you can have a try/catch block around this
> and catch the stack overflow. The handler must be specially written,
> and I describe this in the tutorial of lcc-win32. Obviously this is
> a non portable solution.
^^^^^^^^^^^^^^^^^^^^^

Ding, ding, ding! We have a winner!

We should stick to the (less-widely available) C99 standard because
it offers so much more, like VLAs. But, to avoid the inherent UB
of using VLAs, we should stick to non-standard, non-portable
workaround?

And are try/catch part of C99?

Kenneth Brody

unread,
Aug 2, 2006, 10:59:41 AM8/2/06
to
Walter Roberson wrote:
>
> In article <44CF7E5D...@spamcop.net>,
> Kenneth Brody <kenb...@spamcop.net> wrote:
> >Flash Gordon wrote:
>
> >> puts("Do not post to comp.lang.c at almost 2AM.");
>
> >Nor should you post at 3:30AM.
>
> >No terminating newline in your output.
>
> puts() automatically adds newline.

Yeah, but... Umm... Err... Oops... :-(

Shows you how long it's been since I've used puts().

Walter Roberson

unread,
Aug 2, 2006, 12:18:59 PM8/2/06
to
In article <44cf9448$0$853$ba4a...@news.orange.fr>,
jacob navia <ja...@jacob.remcomp.fr> wrote:
>Walter Roberson wrote:

>> puts() automatically adds newline.

>You are cheating since you posted at 19:35...

It was about 12:35 here; 19:35... hmmm, that would have been
some european summer time zone.
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest

Chris Torek

unread,
Aug 3, 2006, 6:12:34 AM8/3/06
to
>In article <ean6p...@news1.newsguy.com> Chris Torek
><nos...@torek.net> writes:
>> [VLAs] allow you to write matrix algebra of the sort

>> that Fortran has had for years:
>>
>> void some_mat_op(int m, int n, double mat[m][n]) {
>> ...
>> }

In article <J3CF2...@cwi.nl>, Dik T. Winter <Dik.W...@cwi.nl> wrote:
>This is something different. You are dimensioning the arguments here.

Different from what? (It is still a VLA, or at least, it is in the
draft C99 standard I use.)

>What it solves is problems like:
> void some_mat_op(int m, int n, double mat[m][n]) {
> double temp[m][n];
> ...
> }

It does this too; but being able to give variable dimensions for
a parameter is valuable on its own. It avoids any need to fake
out the routine with code like this:

void some_mat_op(int m, int n, double *mat) {
... refer to mat[i * n + j] instead of mat[i][j] ...
}
...
void f(void) {
double mat[300][5];
...
some_mat_op(300, 5, &mat[0][0]);
...
}

which is not even strictly valid in C89/C90 (due to out-of-bounds
subscript usage in some_mat_op(), whenever i>0). The faked-out
version usually works; but one is at least skating on thin ice,
and of course the C99 version is much more convenient.

>something that Fortran has only since 1990.

Well, this is still "years" :-)

>[Automatic duration, runtime-sized arrays were] in Algol 60 from
>the very beginning.

As has oft been said, Algol was an improvement on its successors. :-)
--
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.

Dik T. Winter

unread,
Aug 3, 2006, 7:19:51 AM8/3/06
to
In article <easi6...@news3.newsguy.com> Chris Torek <nos...@torek.net> writes:
> >In article <ean6p...@news1.newsguy.com> Chris Torek
> ><nos...@torek.net> writes:
> >> [VLAs] allow you to write matrix algebra of the sort
> >> that Fortran has had for years:
> >>
> >> void some_mat_op(int m, int n, double mat[m][n]) {
> >> ...
> >> }
>
> In article <J3CF2...@cwi.nl>, Dik T. Winter <Dik.W...@cwi.nl> wrote:
> >This is something different. You are dimensioning the arguments here.
>
> Different from what? (It is still a VLA, or at least, it is in the
> draft C99 standard I use.)

Different from what Jacob Navia wrote, but I do not remember whether
he wrote it before you or after you.

...
> It does this too; but being able to give variable dimensions for
> a parameter is valuable on its own. It avoids any need to fake
> out the routine with code like this:

...
Indeed.

> >[Automatic duration, runtime-sized arrays were] in Algol 60 from
> >the very beginning.
>
> As has oft been said, Algol was an improvement on its successors. :-)

Certainly for me, as Algol 60 was the first programming language that
I did learn.

0 new messages