Matthew Saltzman wrote:
On Fri, 1 Jun 2007, Mike McCarty wrote:
Les wrote:
On Fri, 2007-06-01 at 07:36 -0400, Matthew Saltzman wrote:
[snip]
NUL character value). The string terminator character is *always*
written '\0'. The machine's representation of that value is
immaterial.
No, the value of the null character is specified...
[snip Standard quote]
Touche. But my real (snipped) point was about representation of null
pointers.
I wasn't trying to score points. I was trying to prevent the
disemination of incorrect material. There is already enough floating
around about C that 'tain't so. We don't need more. I make a regular
habit of checking with the Standard before making statements.
Anyway, that's why I snipped that portion. It was correct.
[snip]
And those systems that used the first location to store the return
address are not re-entrant, without other supporting code in the
background. I think I used one of those once as well.
There's no requirement for re-entrancy in K&R or ANSI/ISO. In fact
several standard library routines are known to not be re-entrant.
Each implementation is its own. There is no fact about all
implementation of library routines.
It's pretty hard to implement rand() in a re-entrant way, because it has
I've used a version of rand() which is thread safe. I suspect you may
have as well. Does the implementation you customarily use have pthreads?
Re-entrancy is a slippery word, as it means so many different things
to different people. There are to my knowledge, at least, these
possibilities:
Not reusable, may only ever be called once during the lifetime
of the program. Examples would be subroutines written on the
fly on the execution stack.
Serially reusable, may be called repeatedly, but must not
be called while some thread of execution is using it.
Re-entrant, but blocking, may be called while some thread
of execution is using it, but it blocks if it is already
in use. This type of code may be called from threads, but
not from interrupt handlers, for example.
Re-entrant, non-blocking, non-recursive, does not block
if called while some thread of execution is already using
it, but may not be entered from within itself. This kind
of code may not be called in such a manner that it may
eventually winds up re-invoking itself from some function
it may call. Such functions may not be called from any
interrupt handler which may still be running when the next
interrupt happens, for example.
Recursive, no restriction on use.
to maintain a static internal state. There are a couple of string.h
functions that maintain static internal state information as well, where
repeated calls with the same argument string continue scanning the
string from where the previous call left off.
These must be duplicated per thread for them to be thread safe.
Such implementations exist.
This is true, but knowing that the base code is not reentrant due to
design constraints or due to hardware constraints makes the difference
on modern multithreaded systems, where the same executable memory can be
used for the program (if the hardware allows that).
Every conforming implementation of C must make it such that all
functions are reentrant and must support recursion. How much work
that is on any given hardware depends on how closely the hardware
corresponds to the requirements.
Not all functions can be made re-entrant.
All functions may be made re-entrant but blocking.
Mike
--
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
Oppose globalization and One World Governments like the UN.
This message made from 100% recycled bits.
You have found the bank of Larn.
I can explain it for you, but I can't understand it for you.
I speak only for myself, and I am unanimous in that!