N
Nick Keighley
You're still not understanding.
The mere FACT of accessing random garbage memory is undefined behavior.
it might be unmapped memory, or unwriteable memory or code.
<snip>
You're still not understanding.
The mere FACT of accessing random garbage memory is undefined behavior.
GIGO still applies. IIRC, the term was invented for C.
I don't know about you, but I can always find a way to guarantee my code
will never be stuck in an infinite loop.
Despite what you believe, I did.
Assume an implementation where a pointer consists of two parts: a segment
identifier and an offset.
On allocation, the OS reserves a virtual memory region - which may well
not have any actual memory behind it. On read or write, the OS detects a
fault (no memory page mapped), sorts out how to handle it, digs up a
usable page of memory, maps it in and away you go, reading or writing.
Then you free the memory, telling the OS that the virtual memory region
is now invalid, that it does not exist.
What happens now, if you try to - as you say - "try and trim the
garbage"? You read a byte, the system faults, the OS's memory manager
kicks in to load the associated page of memory, but there _is no_
associated page of memory. You are trying to access memory which _does
not exist_. The app - if you're lucky - is summarily killed by the OS
for trying to poke its nose into memory it doesn't own.
In C terms, by calling "free", you disposes of the object in question,
but then attempted to examine the object after the fact. C's answer to
this is "undefined behaviour", where *any* outcome is perfectly
acceptable: crashing, "working", trashing memory belonging to other
processes, setting your CPU on fire, causing your kitten to tie you up
and flog you with damp tea bags, it's _all_ perfectly acceptable as far
as C is concerned.
Once that pointer has become invalid, there is simply _no manner_ in
which you can use it, for any meaningful operation, other than assigning
a new value to it - which does not help one bit in trying to do what
you're seeking to accomplish.
Standards conformance has its place, but how can you protect yourself if
you don't explore UB and learn how things really work.
On most CPUs (especially modern ones), memmove() cannot be
implemented in one assembly instruction.
Even if it can, that
instruction must perform a pass over the data; it's going to be O(N),
where N is the number of bytes moved. There's nothing magical about
microcode.
memmove() is likely to be faster than an equivalent C loop, but
only by a constant factor, and probably a fairly small one.
He's not. You made the assertion that memmove was "probably" not
equivalent to a "pass" -- even though it's trivially obvious that
it MUST be in order for its operation to be carried out. Keith
correctly pointed out that this somewhat topical assertion was wrong.
His post is not a rant, and is in no way off topic; questions of
what memmove() is or isn't are pretty topical. Programmers who
wish to make good use of C should know that, while usually efficient,
memmove() is not a magical tool for bypassing performance
considerations. In particular, this magical "one assembly
instruction" is both implausible (in general) and misleading -- you
seem to think that performance is purely a function of number
of instructions, but again, in real-world cases, user-provided C
loops which compile into complicated loops in assembler have been
known to outperform dedicated hardware functions by a large margin.
I think you're talking to a wall here. Kelly's in all the world's a
VAX mode -- he's assuming a flat memory model where you can do whatever
you want to pointers, as long as you "avoid overflow", which is totally
incoherent -- but since he dismisses any platform which doesn't conform
to his /a priori/ assumptions as broken or uninteresting, it hardly
matters.
Define symbols and (words)
exam ......... temporary char *
hast ......... temporary char * to alpha !isspace
hath ......... temporary char **
keep ......... temporary char * to omega !isspace
trimlen ...... trimmed string length
ts ........... temporary char * to string
ts ........... temporary string []
tu ........... temporary size_t
xu ........... fail safe size_t
Unfortunately, errno gets clobbered by any function that sees fit to
put its error there.
It's more of a portability issue, where
different functions on different systems like to put their error codes
there. Does a malloc failure set errno to ENOMEM? On some it does
and others it does not.
Functions should NEVER crash no matter
how bad the input.
The only diagnostic a library function should emit is the result of an
assert!
John Kelly said:You are thinking of C strings. There are no "bounds" to a pointer.
Seebs said:I think you're talking to a wall here. Kelly's in all the world's a
VAX mode -- he's assuming a flat memory model where you can do whatever
you want to pointers, as long as you "avoid overflow", which is totally
incoherent -- but since he dismisses any platform which doesn't conform
to his /a priori/ assumptions as broken or uninteresting, it hardly
matters.
Basically, he figures that since the results he's seen so far didn't
include infinite loops, it can never happen.
Ian Collins said:Define symbols and (words)
exam ......... temporary char *
hast ......... temporary char * to alpha !isspace
hath ......... temporary char **
keep ......... temporary char * to omega !isspace
trimlen ...... trimmed string length
ts ........... temporary char * to string
ts ........... temporary string []
tu ........... temporary size_t
xu ........... fail safe size_t
Why don't you just your variables meaningful names, rather then having
to annotate them? It's bad enough in old C having to scroll to the
top to find declarations, without having to go even further to see
what they do.
John Kelly said:John Kelly said:[...]
and one write pass?
Probably, memmove() is not equivalent to a "pass." If it's one assembly
instruction, zoom!
On most CPUs (especially modern ones), memmove() cannot be
implemented in one assembly instruction. Even if it can, that
instruction must perform a pass over the data; it's going to be O(N),
where N is the number of bytes moved. There's nothing magical about
microcode.
memmove() is likely to be faster than an equivalent C loop, but
only by a constant factor, and probably a fairly small one.
Why are you indugling in off topic rants?
John Kelly said:[...]
and one write pass?
Probably, memmove() is not equivalent to a "pass." If it's one assembly
instruction, zoom!
On most CPUs (especially modern ones), memmove() cannot be
implemented in one assembly instruction. Even if it can, that
instruction must perform a pass over the data; it's going to be O(N),
where N is the number of bytes moved. There's nothing magical about
microcode.
memmove() is likely to be faster than an equivalent C loop, but
only by a constant factor, and probably a fairly small one.
Why are you indugling in off topic rants?
I'm curious -- what led you to think that the above was either off topic
or a rant?
There are, both in theory and in practise.
When I originally asked you to say what the contract was between the
caller and the callee, this was one of the things that you could ave
specified: the code works only on such-and-such type machines. In
effect you did specify that when you said the contract is defined by
what the code does. I.e. you wrote trim for machines where it works
and, presumably, you don't care about ones where it won't.
John Kelly said:You are thinking of C strings. There are no "bounds" to a pointer.
You can increment a pointer until it wraps back to 0, and repeat that
loop forever.
If you try to read that memory, you may segfault and terminate. But
that is beside the point. My code copes with an abstract machine where
one process owns all the memory, from 0 to the highest address.
That may not be a real world scenario, but again, that is beside the
point. My code copes with abstract near impossibilities. That's the
way a programmer should think.
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.