468,457 Members | 1,711 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

The illusion of "portability"

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

Jul 31 '06
93 3429
>"Frederick Gotham" <fg*******@SPAM.comwrote in message
>news:oP*******************@news.indigo.ie...
>>>Arrays whose length is known at compile time are far more efficient to work
with.
>dc*****@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 <44*********************@news.orange.fr>
jacob navia <ja***@jacob.remcomp.frwrote:
>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().
--
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.
Aug 1 '06 #51
[On testing for "printf" failure by using
fflush(stdout);
if (ferror(stdout)) ...
at the end of the program]

In article <gb********************************@4ax.com>
jaysome <ja*****@spamcop.netwrote:
>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.
--
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.
Aug 1 '06 #52
In article <ea*********@news1.newsguy.comI 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.)
--
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.
Aug 1 '06 #53
dc*****@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
Aug 1 '06 #54
On 2006-08-01, Old Wolf <ol*****@inspire.net.nzwrote:
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))
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
Aug 1 '06 #55
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.
Aug 1 '06 #56
jacob navia wrote:
Keith Thompson a écrit :
>jacob navia <ja***@jacob.remcomp.frwrites:
>>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.
Aug 1 '06 #57
"Old Wolf" <ol*****@inspire.net.nzwrites:
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
Aug 1 '06 #58
jaysome <ja*****@spamcop.netwrites:
On Mon, 31 Jul 2006 15:55:23 -0700, Ben Pfaff <bl*@cs.stanford.edu>
wrote:
>>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.
You can test it with system-specific features, e.g. /dev/full. I
don't recall whether I did so, though.
--
"I don't have C&V for that handy, but I've got Dan Pop."
--E. Gibbons
Aug 1 '06 #59
Richard Heathfield <in*****@invalid.invalidwrites:
Ben Pfaff said:
>Frederick Gotham <fg*******@SPAM.comwrites:
>>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,0xa6 7f6aaa,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;}}}
Aug 1 '06 #60
On 31 Jul 2006 18:34:34 -0700, dc*****@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
Aug 1 '06 #61
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:Th*************@gmail.com>
Aug 1 '06 #62
Gernot Frisch wrote:
>
>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 ;)
A "great" programmer can even write it in FORTRAN.

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

Aug 1 '06 #63
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.
Aug 1 '06 #64
Ben Pfaff said:
Richard Heathfield <in*****@invalid.invalidwrites:
<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?

--
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)
Aug 1 '06 #65
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 J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Aug 1 '06 #66
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 J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Aug 1 '06 #67
dc*****@connx.com wrote:
>
Keith Thompson wrote:
[...]
dc*****@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 J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Aug 1 '06 #68
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.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Aug 1 '06 #69
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().

--
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)
Aug 1 '06 #70
In article <44***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
>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
Aug 1 '06 #71
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.

Aug 1 '06 #72
Walter Roberson wrote:
In article <44***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
>>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...

:-)

Aug 1 '06 #73
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

Aug 1 '06 #74
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.
Aug 1 '06 #75
Skarmander wrote:
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.)
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.
Aug 1 '06 #76
Richard Heathfield <in*****@invalid.invalidwrites:
Ben Pfaff said:
>Richard Heathfield <in*****@invalid.invalidwrites:
>>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.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,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;}}}
Aug 1 '06 #77
On 2006-08-01, Ben Pfaff <bl*@cs.stanford.eduwrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:
>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.)

--
Andrew Poelstra <website down>
To reach my email, use <email also down>
New server ETA: 42
Aug 1 '06 #78
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.
Aug 1 '06 #79
Kenneth Brody <ke******@spamcop.netwrites:
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.
Aug 1 '06 #80
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
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.

--
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.
Aug 1 '06 #81
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>>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.

Aug 1 '06 #82
jacob navia <ja***@jacob.remcomp.frwrites:
Keith Thompson wrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>>>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.

--
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.
Aug 1 '06 #83
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
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

Aug 1 '06 #84
In article <ea*********@news1.newsguy.comChris Torek <no****@torek.netwrites:
In article <4r********************@bt.com>
Richard Heathfield <in*****@invalid.invalidwrote:
....
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/
Aug 1 '06 #85
"Peter Nilsson" <ai***@acay.com.auwrites:
Keith Thompson wrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
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).

--
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.
Aug 1 '06 #86
In article <ln************@nuthaus.mib.orgKeith Thompson <ks***@mib.orgwrites:
"Peter Nilsson" <ai***@acay.com.auwrites:
....
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.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Aug 2 '06 #87
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!
Aug 2 '06 #88
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.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Aug 2 '06 #89
jacob navia wrote:
>
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
[... 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 J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Aug 2 '06 #90
Walter Roberson wrote:
>
In article <44***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
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().

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Aug 2 '06 #91
In article <44*********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>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
Aug 2 '06 #92
>In article <ea*********@news1.newsguy.comChris Torek
><no****@torek.netwrites:
>[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 <J3********@cwi.nl>, Dik T. Winter <Di********@cwi.nlwrote:
>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.
Aug 3 '06 #93
In article <ea********@news3.newsguy.comChris Torek <no****@torek.netwrites:
In article <ea*********@news1.newsguy.comChris Torek
<no****@torek.netwrites:
[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 <J3********@cwi.nl>, Dik T. Winter <Di********@cwi.nlwrote:
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.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Aug 3 '06 #94

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.