J
jacob navia
This discussion started in the thread:
"Help a beginner - simple lowercase to uppercase and so on function"
but it has actually nothing to do with the subject of that thread so I
start a new one.
My arguments for justifying the thesis in the subject line are:
o It makes the function not restartable
o Under the debugger you can't know what was the parameter you
received when the function misbehaves. You can't debug it.
o The small gain in storage space is not worth the associated risks.
To my surprise, the eternal heathfield doesn't agree with this obvious
stuff.
He says to the first point:
Well, apparently he doesn't get it. Suppose a function
int fn(int a)
{
// some code
a = 56;
// more code
}
After that assignment it is impossible to go to the first line of the
function and restart it, since the original value of a is lost.
This is completely obvious but somehow not obvious to some.
To the second point, he argues ( I cite again the second point
for clarity)
<heathfield>
Maybe you can't, but I can - by setting a breakpoint at an
appropriate place and making a note of the value before the mod.
<end of heathfield>
The obvious situation where the function is called 4765 times
before it crashes doesn't occur to him. Maybe because he has never been
in the frustrating situation of trying to know what is the specific
parameter that makes the function crash.
He continues:
<heathfield>
What risk do you see in:
void intcopy(int *s, int *t, int term)
{
while((*s++ = *t++) != term) {}
}
< end of heathfield>
I see MANY risks in that construct, the first and foremost
is that "t" is a vector of integers that is MISSING the
"term" terminator!
Of course THAT "can't happen", and heathfield doesn't even consider
that case.
BUT, let's suppose that this happens, since in the real world,
bugs DO appear.
How you will see the effects of that?
(1) The program as written will crash when it arrives at the end of
available memory . Since you do not have the original data, you
can't figure out what parameters were passed in.
(2) The program will find a random integer in memory that
corresponds to "term", after having overwritten a lot of memory.
That function will return as if nothing had happened leaving
the rest of the software in an unknown state. Since this depends
on the contents previously stored in unknown data areas, the
program will (or will not) go on, maybe crashing sometimes
or (worst) never crashing but giving *sometimes* strange results or
crashes hours later.
(3)
Another obvious problem with the function above is that no SIZE
information is passed to limit the copy, so that if "s" points to
an area too small to receive "t" a buffer overflow will happen.
That has in principle nothing to do with the modification of the
parameters but having the parameters still available it would
allow you to see the corresponding address and you can figure out
its size and location within the debugger.
Actually, I wanted to highlite this problem because I consider that
functions like "intcopy" are the ideal example of how NOT to program
in C.
o Function modifies its parameters. Not restartable, not debuggable.
o No error analysis at all (return value void)
o The slightest error in the calling function when passing the
parameters leads to debugging nightmares.
It is funny that another "regular" (Mr Ben Pfaff) says:
<quote Mr Pfaff>
I would say that the latter is riskier, because there are more
entities for me to keep track of as I read it. It is easier to
understand the behavior of three variables than five.
<end of quote>
The brain of Mr Pfaff has difficulties reading:
Imagine the problems Mr Pfaff would have if we pass size information
to make better designed software!
I can only recommend to him to stop programming. Reading NO variables
at all is surely even easier to do.
Conclusion:
a) Do not modify the parameters of a function. It is a bad idea.
b) Think about the debugging of the functions when you write them.
If you do that, you will avoid monstrosities like the above
"intcopy".
c) Do not follow the advise of heathfield (and co)...
"Help a beginner - simple lowercase to uppercase and so on function"
but it has actually nothing to do with the subject of that thread so I
start a new one.
My arguments for justifying the thesis in the subject line are:
o It makes the function not restartable
o Under the debugger you can't know what was the parameter you
received when the function misbehaves. You can't debug it.
o The small gain in storage space is not worth the associated risks.
To my surprise, the eternal heathfield doesn't agree with this obvious
stuff.
He says to the first point:
> You lost me. I am sure it is possible to construct a function in
> which modifying its parameter makes it non-restartable, but you
> don't /have/ to construct functions that way.
Well, apparently he doesn't get it. Suppose a function
int fn(int a)
{
// some code
a = 56;
// more code
}
After that assignment it is impossible to go to the first line of the
function and restart it, since the original value of a is lost.
This is completely obvious but somehow not obvious to some.
To the second point, he argues ( I cite again the second point
for clarity)
<end of jn quote>> o Under the debugger you can't know what was the parameter
> you received when the function misbehaves. You can't debug it.
<heathfield>
Maybe you can't, but I can - by setting a breakpoint at an
appropriate place and making a note of the value before the mod.
<end of heathfield>
The obvious situation where the function is called 4765 times
before it crashes doesn't occur to him. Maybe because he has never been
in the frustrating situation of trying to know what is the specific
parameter that makes the function crash.
He continues:
<heathfield>
What risk do you see in:
void intcopy(int *s, int *t, int term)
{
while((*s++ = *t++) != term) {}
}
< end of heathfield>
I see MANY risks in that construct, the first and foremost
is that "t" is a vector of integers that is MISSING the
"term" terminator!
Of course THAT "can't happen", and heathfield doesn't even consider
that case.
BUT, let's suppose that this happens, since in the real world,
bugs DO appear.
How you will see the effects of that?
(1) The program as written will crash when it arrives at the end of
available memory . Since you do not have the original data, you
can't figure out what parameters were passed in.
(2) The program will find a random integer in memory that
corresponds to "term", after having overwritten a lot of memory.
That function will return as if nothing had happened leaving
the rest of the software in an unknown state. Since this depends
on the contents previously stored in unknown data areas, the
program will (or will not) go on, maybe crashing sometimes
or (worst) never crashing but giving *sometimes* strange results or
crashes hours later.
(3)
Another obvious problem with the function above is that no SIZE
information is passed to limit the copy, so that if "s" points to
an area too small to receive "t" a buffer overflow will happen.
That has in principle nothing to do with the modification of the
parameters but having the parameters still available it would
allow you to see the corresponding address and you can figure out
its size and location within the debugger.
Actually, I wanted to highlite this problem because I consider that
functions like "intcopy" are the ideal example of how NOT to program
in C.
o Function modifies its parameters. Not restartable, not debuggable.
o No error analysis at all (return value void)
o The slightest error in the calling function when passing the
parameters leads to debugging nightmares.
It is funny that another "regular" (Mr Ben Pfaff) says:
<quote Mr Pfaff>
I would say that the latter is riskier, because there are more
entities for me to keep track of as I read it. It is easier to
understand the behavior of three variables than five.
<end of quote>
The brain of Mr Pfaff has difficulties reading:
> void intcopy(int *s, int *t, int term)
> {
> int *u = s;
> int *v = t;
> while((*u++ = *v++) != term) {}
> }
Imagine the problems Mr Pfaff would have if we pass size information
to make better designed software!
I can only recommend to him to stop programming. Reading NO variables
at all is surely even easier to do.
Conclusion:
a) Do not modify the parameters of a function. It is a bad idea.
b) Think about the debugging of the functions when you write them.
If you do that, you will avoid monstrosities like the above
"intcopy".
c) Do not follow the advise of heathfield (and co)...