Learning C as an existing programmer

I

Ike Naar

since when have these been macros?

In C99 they are listed under the macros section in

7.19 Input/output <stdio.h>

7.19.1 Introduction
The header <stdio.h> declares three types, several macros, and many
functions for performing input and output.

[...]

3 The macros are

[...]

stderr
stdin
stdout

which are expressions of type "pointer to FILE" that point to FILE
objects associated, respectively, with the standard error, input, and
output streams.
 
G

gwowen

Secondly, your characterisation of the size is, err... provocative.

No. I mean "trivially small" in the sense that "it really doesn't
matter how many of these you have, something else will blow up first,
so don't worry about it."
All arrays (malloced or otherwise) are of bounded size so (i) is a red
herring.

They're not bounded at compile time, or at the time you set the stack-
size. Arrays are often dependent on the input size, and often non-
linearly so (say calculating a Gram matrix). If you don't know the
input size in advance, and it might be large, VLAs are a non-starter.

Again, VLAs are fine if and only if,
i) if you, or your library user, knows the maximum input size in
advance,

ii) you're happy doing the worst-case stack calculation by hand and
setting a sufficient stacksize [or, better, leave this to your users!]
(good luck if you're doing an adaptive / multiscale grid solver)

iii) you don't mind undefined behaviour if someone get that
calculation wrong...
 
G

gwowen

What you mean is that VLAs have no portably guaranteed failure
mechanism.  On a particular implementation they may very well
have a well-defined, implementation-supplied, such mechanism.


Well, yes. But you could say the same for NULL pointer dereferences.
The only difference is that implentations that give predictable
behaviour for NULL pointer dereferences actually exist, as opposed to
being completely theoretical.
 
J

jacob navia

Le 26/06/12 11:38, gwowen a écrit :
Secondly, your characterisation of the size is, err... provocative.

No. I mean "trivially small" in the sense that "it really doesn't
matter how many of these you have, something else will blow up first,
so don't worry about it."
All arrays (malloced or otherwise) are of bounded size so (i) is a red
herring.

They're not bounded at compile time, or at the time you set the stack-
size. Arrays are often dependent on the input size, and often non-
linearly so (say calculating a Gram matrix). If you don't know the
input size in advance, and it might be large, VLAs are a non-starter.

Again, VLAs are fine if and only if,
i) if you, or your library user, knows the maximum input size in
advance,

ii) you're happy doing the worst-case stack calculation by hand and
setting a sufficient stacksize [or, better, leave this to your users!]
(good luck if you're doing an adaptive / multiscale grid solver)

iii) you don't mind undefined behaviour if someone get that
calculation wrong...


Look, when you do:

int fn(void)
{
double table[4096];
}

There is no failure indication if there wasn't any more stack space for
allocating 4096 doubles.

VLA's are the same.

Conclusion:

Be careful with the stack.
 
J

jacob navia

Le 26/06/12 12:13, jacob navia a écrit :
Conclusion:

Be careful with the stack.


Excuse me. Of course I know that C "has no stack", and that the standard
doesn't mention the word stack, etc.

So we can spare us that discussion again :)
 
J

James Kuyper

this isn't a universal convention- though it's a common one

If he's talking only about C keywords and standard C library identifiers
(which he has not explicitly stated), then I think he's correct.
 
G

Guest

בת×ריך ×™×•× ×©× ×™, 25 ביוני 2012 22:27:02 UTC+1, מ×ת Tim Rentsch:
And these days if you're writing C you're probably more likely to be writing components rather than complete programs. A component does know what todo on out of memory -sometimes relying on the OS to kill the process is the best you can do, sometimes its completely unacceptable.

ITYM "A component does *not* know what to do on out of memory..."
 
R

Rui Maciel

David said:
I agree - that's why I am suggesting the OP looks at alternatives that
might be a better choice overall, rather than following the "only C is
fast enough" fanboyism.

If you read the thread you will notice two things.

The first one is that no one, besides yourself in this post, said that "only
C is fast enough" or any similar nonsense. I don't know why you felt the
need to invent this, particularly in reply to a post where C was explicitly
mentioned on par with fortran in this criteria.

The second thing is that four completely different tools were mentioned as
being appropriate for numerical analysis applications: Fortran, C, Matlab
and Octave. It's silly to throw accusations of fanboyism based on a
suggestion of four different and competing tools. It's even sillier when
you do that to try to defend your pet tool.


Rui Maciel
 
I

Ian Collins

Le 26/06/12 11:38, gwowen a écrit :
Secondly, your characterisation of the size is, err... provocative.

No. I mean "trivially small" in the sense that "it really doesn't
matter how many of these you have, something else will blow up first,
so don't worry about it."
All arrays (malloced or otherwise) are of bounded size so (i) is a red
herring.

They're not bounded at compile time, or at the time you set the stack-
size. Arrays are often dependent on the input size, and often non-
linearly so (say calculating a Gram matrix). If you don't know the
input size in advance, and it might be large, VLAs are a non-starter.

Again, VLAs are fine if and only if,
i) if you, or your library user, knows the maximum input size in
advance,

ii) you're happy doing the worst-case stack calculation by hand and
setting a sufficient stacksize [or, better, leave this to your users!]
(good luck if you're doing an adaptive / multiscale grid solver)

iii) you don't mind undefined behaviour if someone get that
calculation wrong...

Look, when you do:

int fn(void)
{
double table[4096];
}

There is no failure indication if there wasn't any more stack space for
allocating 4096 doubles.

But you can do a static analysis (unless recursion is in the frame) of
stack use with fixed size allocations. I've been through that pain a
few times on embedded systems.
VLA's are the same.

Not really, they do open another can of worms.
Conclusion:

Be careful with the stack.

Quite!
 
S

Stefan Ram

gwowen said:
Well, yes. But you could say the same for NULL pointer dereferences.

One can always guard: »if(p)*p;«, I am not aware of the corresponding
guard for VLAs.

The spelling of N1570 is »null pointer« (not »NULL pointer«).
 
T

Tim Rentsch

Malcolm McLean said:
Tim Rentsch:
And these days if you're writing C you're probably more likely to be
writing components rather than complete programs. A component does
know what to do on out of memory -sometimes relying on the OS to
kill the process is the best you can do, sometimes its completely
unacceptable.

Completely beside the point I was making, as using malloc() is
no different in this regard.
 
S

Stefan Ram

Tim Rentsch said:
not?

as using malloc() is no different in this regard.

When a library-grade function needs to allocate memory
and this fails, it knows what to do: Notify the caller
of the failure (usually via a status code).
 
T

Tim Rentsch

gwowen said:
Well, yes. But you could say the same for NULL pointer dereferences.
The only difference is that implentations that give predictable
behaviour for NULL pointer dereferences actually exist, as opposed to
being completely theoretical.

(Linguistic nit: 'hypothetical' is probably a better word choice
than 'theoretical'. But no matter...)

I don't disagree, but the distinction is still important. There
is no reason an implementation couldn't allocate VLAs outside
the regular stack space (eg, using malloc()/free() or something
like them), keeping only a pointer to the allocated space in
the stack frame. This isn't even that hard to do. In such an
implementation it's really easy to deal with VLA allocation
failure, eg,

double product[m][n];
if( ! &product ) ...

Now here comes the interesting part. Suppose this idiom were
commonly followed. Compilers certainly could check for it,
and substitute a check for sufficient stack space being available
for the VLA (ie, before adjusting the stack pointer to allocate
the VLA in the stack frame). The result is we have VLAs that
are implemented just like the VLAs we're used to now, except
there is an easy way to deal with allocation failure. And no
language changes required -- just smarter implementations.

Obviously it would be better if such a scheme were blessed in
the language standard, so it could be used portably. In the
meantime, however, it can easily be implemented now, without
any language changes needed. That the existing standard
accommodates such a scheme is a significant property.
 
T

Tim Rentsch

One can always guard: >>if(p)*p;<<, I am not aware of the corresponding
guard for VLAs.

If the variable 'v' is a VLA, a test like 'if( ! &v )' might check for
allocation failure. This doesn't work now, but it easily could,
first in particular implementations, later incorporated into the
Standard. C 202X, anyone?
 
T

Tim Rentsch

When a library-grade function needs to allocate memory
and this fails, it knows what to do: Notify the caller
of the failure (usually via a status code).

You snipped too much context. If a piece of code isn't
able to deal with an allocation failure, it doesn't matter
where the allocation falure came from. If a piece of
code is able to deal with allocation failure in some way,
that applies equally to allocation failures for malloc()
and VLAs, assuming of course that VLA allocation failure
can be detected, which I pointed out upthread that it
can in a conforming implementation, if the implementation
so desires. The ability or non-ability of some piece of
code to respond sensibly to allocation failure has no
bearing on the point I was making.
 
B

Ben Bacarisse

gwowen said:
No. I mean "trivially small" in the sense that "it really doesn't
matter how many of these you have, something else will blow up first,
so don't worry about it."

I don't know what this means. Sounds like more polemic, but maybe there
is a significant point here.
They're not bounded at compile time, or at the time you set the stack-
size. Arrays are often dependent on the input size, and often non-
linearly so (say calculating a Gram matrix). If you don't know the
input size in advance, and it might be large, VLAs are a non-starter.

So by "not bounded" you meant that the size is not known at compile
time. That's the essence of VLAs. This criticism is that VLAs are
a non-starter because they are VLAs.
Again, VLAs are fine if and only if,
i) if you, or your library user, knows the maximum input size in
advance,

ii) you're happy doing the worst-case stack calculation by hand and
setting a sufficient stacksize [or, better, leave this to your users!]
(good luck if you're doing an adaptive / multiscale grid solver)

Straw man. Who said anything about doing an adaptive / multiscale grid
solver with stack-allocated VLAs?
iii) you don't mind undefined behaviour if someone get that
calculation wrong...

Do you do ii) and accept iii) for all your programs, because they apply
in the absence of VLAs? I don't. Most of the time I just assume that I
don't run out of stack and that if I do my system will let me know.
There are cases when the same rough and ready approach works with VLAs.
 
8

88888 Dihedral

Ben Bacarisseæ–¼ 2012å¹´6月27日星期三UTC+8上åˆ8時55分59秒寫é“:
gwowen said:
No. I mean "trivially small" in the sense that "it really doesn't
matter how many of these you have, something else will blow up first,
so don't worry about it."

I don't know what this means. Sounds like more polemic, but maybe there
is a significant point here.
They're not bounded at compile time, or at the time you set the stack-
size. Arrays are often dependent on the input size, and often non-
linearly so (say calculating a Gram matrix). If you don't know the
input size in advance, and it might be large, VLAs are a non-starter.

So by "not bounded" you meant that the size is not known at compile
time. That's the essence of VLAs. This criticism is that VLAs are
a non-starter because they are VLAs.
Again, VLAs are fine if and only if,
i) if you, or your library user, knows the maximum input size in
advance,

ii) you're happy doing the worst-case stack calculation by hand and
setting a sufficient stacksize [or, better, leave this to your users!]
(good luck if you're doing an adaptive / multiscale grid solver)

Straw man. Who said anything about doing an adaptive / multiscale grid
solver with stack-allocated VLAs?
iii) you don't mind undefined behaviour if someone get that
calculation wrong...

Do you do ii) and accept iii) for all your programs, because they apply
in the absence of VLAs? I don't. Most of the time I just assume that I
don't run out of stack and that if I do my system will let me know.
There are cases when the same rough and ready approach works with VLAs.


In the developement and debugging phase,
it is very common to use recursion based functions which
use the stack.

But if the function under development is critical,
then the depth of the stack used should be
tested rigorously to find the bounded depth of the stack in practical
applications in order that the function can be rewritten
as a non-recursive version.
 
J

James Kuyper

Well, that was sort of my original point.


I am not a standardisation document.

Yes, but you are someone who's trying to communicate meaningfully about
C. Using correct terminology when doing so improves your chances of
being understood correctly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,205
Latest member
ElwoodDurh

Latest Threads

Top