C
CBFalconer
pete said:ptr_diff is too small.
Why not just use strlen?
Because all this is illustrations of cases for the subject line,
not practical proposals. You snipped the whole raison d'etre.
pete said:ptr_diff is too small.
Why not just use strlen?
Tim said:What connection would that be? Declaring a parameter 'const'
(the parameter itself, not something it points to) doesn't
impose any burden on any call site.
Of course, after all the fuss, this is a function that can be
improved by not altering the input parameter.
size_t length_of_string(const char *s) {
const char *t = s;
while (*t++) continue;
return t - s;
}
(and I will live with the possibility that ptr_diff is too small)
ptr_diff is too small.
Why not just use strlen?
I know where you're coming from. What code seems "natural" to
people certainly varies from person to person.
Even though this
example wasn't the best, however, I hope you can see the
principle that I'm trying to illustrate. Consider two versions
of matrix multiplication, for example - one written out using
arrays and normal index calculations, the other using pointer
variables being changed and updated with only plus and minus.
The "less imperative" version that uses arrays and just simple
loops with i,j,k index variables is more likely to be easy
to understand.
(I'm assuming you meant to write slightly different code that
returned the same value but caused the destination string to be
null-terminated. Please read the comments below as if that
code were written above.)
I think we're in agreement that there are cases (the above
probably being one) where modifying the paramters yields a
better-overall function body. Where we may disagree is what
the magnitude of the difference is. The function body above
re-written to use locals rather than modifying its parameters
might be a line or two longer, but I don't think I'd say that
code would obscure things. Perhaps I'm just more used to a
style that almost never modifies parameters.
In practice it sounds like our views are actually pretty
similar. I appreciate the comments.
CBFalconer said:It restricts the freedom of action when revising the function, to
no purpose. We are not talking about pointers here, but actual
value parameters. Modifying them cannot affect anything outside
the function anyhow.
Chris Croughton said:We're not totally opposed, we just draw the lines in different places.
As seen above, I think that you wouldn't have too much problem with most
of my code and I wouldn't have problem with yours, we'd just niggle a
bit about a few frings cases <g>...
And by improved, do you mean broken?Of course, after all the fuss, this is a function that can be
improved by not altering the input parameter.
size_t length_of_string(const char *s) {
const char *t = s;
while (*t++) continue;
return t - s;
}
(and I will live with the possibility that ptr_diff is too small)
Mark said:And by improved, do you mean broken?
You're also living with the fact that:
printf("%d\n", length_of_string(""));
will print 1.
Tim said:You still haven't given any connection between "code modules",
assuming by "code modules" you mean two different sections of
code each at least as big as one function body, which is how I
think most people would read the term.
As to the rest of the comment - lots of people see a benefit in
using 'const' for function-local variables that won't be
modified during function execution. If you choose not to avail
yourself of those benefits, well, that's your prerogative. But
it seems rather silly to say that there are no such benefits.
And by improved, do you mean broken?
You're also living with the fact that:
printf("%d\n", length_of_string(""));
will print 1.
I think of modifying function parameters in much the same way
that I think of using goto. Completely undisciplined use of
goto is bad. Beginners need to be steered away from goto
rather emphatically, because if they aren't they tend to
overuse it. After reaching a certain level of experience and
competence, and mainly having acquired the discipline not to
use it unnecessarily, allowing goto's in certain cases seems
acceptable and reasonable. I use goto myself now and then;
but when I do it's a conscious decision made after considering
and comparing non-goto alternatives.
CBFalconer said:Because all this is illustrations of cases for the subject line,
not practical proposals. You snipped the whole raison d'etre.
Good analogy, although I don't think of modifying function parameters as
being quite as harmful as using goto. ...
CBFalconer said:I've put myself in a peculiar position, for one who espouses Pascal
and the restrictions imposed by strong typing, etc. Here I am
arguing for the elimination of restrictions in C. In part it is
the minimalist in me - I don't want any extra variables declared,
and I don't want any extra restrictions forcing me to so declare.
I consider every extra thing that is needed to be known outside the
connected modules to be a connection. For a normal non-static
function there are three entities involved: The user, the
prototype, and the function. For minimal connectivity there should
be minimal restrictions on the user and the function. In general
we can consider the prototype to be the longest lived of all.
Maybe this makes sense.
It is in some other, non-C languages:
SUBROUTINE FOO(X, I, LAST)
INTEGER I, LAST
REAL X(LAST)
IF (I .GT. LAST) GOTO 20
10 CONTINUE
COMPUT(X(I))
I = I + 1
GOTO 10
20 CONTINUE
RETURN
END
Here, this Fortran code has the obnoxious side effect of incrementing
the variable you call it with:
...
CALL FOO(ARR, I, 20)
C now I .EQ. 21
Perhaps some of the dogmatic "never modify a parameter" is left over
from old Fortran coders.
Chris Croughton said:Actually, it will exhibit undefined behaviour since the function returns
size_t and %d expects an int...
> Since we're being picky, and all...
Chris Croughton said:Oh, I see, you are using CONTINUE as a null statement just to be the
target of the GOTO. Confused me at first, I was looking for the DO...
> SUBROUTINE FOO(X, I, LAST)
> INTEGER I, LAST
> REAL X(LAST)
> IF (I .GT. LAST) GOTO 20
> 10 CONTINUE
> COMPUT(X(I))
> I = I + 1
> GOTO 10
> 20 CONTINUE
> RETURN
> END
>
> Here, this Fortran code has the obnoxious side effect of incrementing
> the variable you call it with:
Actually, it's very well defined on my implementation.
size_t = unsigned int
with value explicitly set to 1 the sign bit is irrelevant.
You've peaked my curiosity, on what implementations
(excluding the infamous DeathStation 9000) is a
size_t not defined as an 'unsigned int' ?
We? Ah, I didn't realize there were two of you!
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.