J
James Kuyper
....
.... Unsigned integers aren't wanted, they're
just a nuisance, a source of confusion and complexity and bugs.
In other words, "Yes".
....
.... Unsigned integers aren't wanted, they're
just a nuisance, a source of confusion and complexity and bugs.
I've just Walled it.On Tue, 06 Aug 2013 12:38:47 -0700, Malcolm McLean wrote:
No, the mode you should use except in special circumstances is conforming
mode, with maximum warning and error reporting. That way, when you get
rid of all the warnings and errors, you have *some* vague hope the code
is actually clean and proper... and it will also, very likely, compile in
"default mode".
Code written with the requirement that one turn off or ignore warnings
and errors, except in very rare cases, is code that simply cannot be
trusted.
I've just Walled it.
(snip)
Some of the warnings weren't bugs, but were legitimate - functions declaring
int return types and then not returning a status. That's just sloppiness,
I prototyped the function before writing it, then didn't change the type
when in fact there were no error conditions. The code's improved as a
result.
I've just Walled it.
Walling did show up some bugs that I'd missed. Only one which was serious,
passing a char instead of an int as a length parameter for a string. Since
the strings will almost always be under 127 chars, this tested OK, but if
the edit box goes wider it might fall over. So that was a catch.
Some of the warnings weren't bugs, but were legitimate - functions declaring
int return types and then not returning a status. That's just sloppiness,
I prototyped the function before writing it, then didn't change the type
when in fact there were no error conditions. The code's improved as a
result.
[...]
Note that before ANSI there was no void, [...]
glen herrmannsfeldt said:Note that before ANSI there was no void, and it was usual for
functions to return int, and no return statement. I believe it
returns zero in that case.
Yes, that one was in the getsavefile function.Did you fix the one where the value of an uninitialized variable was used?
Yes, that one was in the getsavefile function.
It was a bug, but it would have come out pretty quickly.
There's more, e.g. in BBX_FilePicker.c:
static void pressok(void *obj)
{
}
That is the same bug.
When you call bbx_getsavefile it calls pressok() in response to the OK button,
then incorrectly creates the answer from the list rather than from the
edit box.
I was careless in testing that change, and it''s very clearly a bug. But
one that would have come out pretty quickly. The FilePicker dialog is
in a bit of flux, since it doesn't really look nice enough yet.
This presumably makes this (typed into this message) abomination legal:
int func(int parm) {
if(parm > 0) {
printf("I'm positive about things\n");
return -parm;
}
printf("I'm not very positive you know\n");
}
int main(void) {
int x = 27;
...
code to get a value in q
...
if(q > 0)
x = func(y);
else
func(y);
/* x is 27 if q was negative or zero, otherwise it's -q */
....
}
On Sat, 10 Aug 2013 20:11:36 +0100, Dr Nick
No it doesn't. As Keith mentioned, the special rule is only for
main(). Falling off other functions is undefined. C89 has always
allowed you to fall off the end of main() to end the program (again,
that applies to no other function but main()), although the specific
value returned to the system is undefined. C99 strengthens that by
defining the value retuned in that case to be zero.
This presumably makes this (typed into this message) abomination legal:
int func(int parm) {
if(parm > 0) {
printf("I'm positive about things\n");
return -parm;
}
printf("I'm not very positive you know\n");
}
int main(void) {
int x = 27;
...
code to get a value in q
...
if(q > 0)
x = func(y);
else
func(y);
/* x is 27 if q was negative or zero, otherwise it's -q */
....
}
It was. Heaven knows how and why I did that.
That's what I think. Horrible, isn't it?
There are several reasons I can think of. You can't require the compiler
to issue a diagnostic for falling off the end of the function without an
explicit return, because in general, this would require solving the
halting problem. ...
Dr Nick said:That's what I think. Horrible, isn't it?
Richard Damon said:There are several reasons I can think of. You can't require the compiler
to issue a diagnostic for falling off the end of the function without an
explicit return, because in general, this would require solving the
halting problem. The compiler can probably find a lot of cases, and it
can be a good point to issue a warning for a possible falling off the
end without a return (but is really annoying if it complains about no
return at the end of the function which is not reachable, especially if
another compiler you use will then complain about the unreachable return).
You also have legacy code (before void) which might be declared to
return int, but actually just falls off the end. The legacy call point
won't be using the "non-existent" return value, so meets the requirement
of the clause. Without the clause, there would be a good chance of a lot
of "gratuitous" instilled into legacy programs. To my knowledge, no
machine of the period had a problem implementing this exception clause,
it became a "good" compromise.
Richard Damon said:The problem is, you can't, at least unless you provide a solution to the
halting problem. It is quite possible that a path that looks possible is
in fact not possible, perhaps even due to constraints that are not part
of this translation unit.
For the standard to make this a constraint violation, and thus require a
diagnostic, it would need to make some limitations to what the compiler
needs to look at to make some functions that might look like they may
fall of the end of the function, but actually can never do it, in error
and need an "unneeded" return at the end of the function.
Since at the time of the standard was written, compilers did very little
analysis of the program, the rule would need to be very simple and
almost always require the dummy return at the end, wasting bytes of
memory (which were at time precious back then).
Keith Thompson said:(snip)
You *could* require all possible execution paths for a non-void function
to lead to a return statement. C doesn't currently require that kind of
compile-time analysis, but it's not all that difficult to do, and I
think I've seen at least one language that requires it.
So this:
int func(void) {
if (cond) {
return 1;
}
}
would be a constraint violation, but this:
int func(void) {
if (cond) {
return 1;
}
else {
return 0;
}
}
would be valid, since the compiler can prove that the closing } is never
reached. The compiler wouldn't be required to analyze the evaluation of
"cond"; even if it's a constant expression, it would still check for
returns on all paths.
It's already entirely possible for a compiler to warn about such things.
I believe that's why the rule is there. Note that in pre-ANSI code,
functions that didn't return a meaningful value were commonly defined
with no explicit return type; the return type was "int" by default.
Dr Nick said:Although it can't quite be done perfectly. It's possible to imagine a
controlled loop with a conditional return in it where the conditions are
such that the return will always execute before the loop terminates (and
so the loop is effectively an endless loop although not coded as such).
In that case there doesn't need to be a return at the end of the
function but we can make the two clauses of ever increasing complexity
until the compiler has to give up.
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.