C
CBFalconer
Richard said:Richard Tobin said:
Call it again. In fact, call it in a loop. The program is bound
to notice eventually.
If exit returns complain to the C system supplier. It is faulty.
Richard said:Richard Tobin said:
Call it again. In fact, call it in a loop. The program is bound
to notice eventually.
fclose(NULL) is undefined. These two need to be protected with an if
each.
Such a shame that there is no symmetry with malloc/free but
that is how the world is!
christian.bau said:
Yours, if you lose your job when the company goes bust after its flagship
product crashes and burns because you wrote shoddy code despite knowing
better.
Richard Heathfield said:(e-mail address removed) said: [...]The following code from net-snmp library calls atoi five times but
checks none.
Feel free to explain how you'd check atoi. Once you've failed to do that,
you will be in a position to explain why the code is broken.
[email protected] said:or better return or exit earlier when a null returned upon fopen.
[...]Richard Heathfield said:Keith Thompson said: [...]Conceivably the code doesn't need to differentiate between a string
representing 0 and a string that doesn't represent any integer value,
and whatever code calls it will treat either as an error.
Whilst 0 is a common return value for atoi when its input can't be
represented as an int, the Standard doesn't mandate this, so code that
relies on it is broken.
Richard Heathfield said:Keith Thompson said: [...]Conceivably the code doesn't need to differentiate between a string
representing 0 and a string that doesn't represent any integer value,
and whatever code calls it will treat either as an error.Whilst 0 is a common return value for atoi when its input can't be
represented as an int, the Standard doesn't mandate this, so code that
relies on it is broken.
[...]
Good point; I hadn't realized that.
The following is a paraphrase of C99 7.20.1.2 (dropping the references
to atol and atoll for simplicity):
Description
The atoi function converts the initial portion of the string
pointed to by nptr to int representation. Except for the behavior
on error, it is equivalent to
(int)strtol(nptr, (char**)NULL, 10)
Returns
The atoi function returns the converted value.
And a paraphrase from C99 7.20.1.4:
The strtol function returns the converted value, if any. If no
conversion could be performed, zero is returned.
Until a moment ago, I assumed that the *intent* was that atoi()
returns 0 on error, and the standard just didn't express that intent
properly. But that intent could have been expressed simply by
dropping the phrase "Except for the behavior on error". Since it
doesn't say what the behavior on error *is*, the behavior is
undefined.
strtol is said:A side note: Yes, the (char**) cast on the second argument to strtol
in the definition of atoi is necessary. Even in C99, it's still legal
(though unwise) to call strtol without a visible prototype:
/* no #include <stdlib.h> */
long int strtol();
strtol(nptr, NULL, 0); /* UB */
Here NULL is not of type char**, and it won't be converted to char**,
causing undefined behavior.
[email protected] said:or better return or exit earlier when a null returned upon fopen.
I think the sequence of calls to malloc/free is fine provide NULL
initialization performed before malloc.
Ben said:OK, but then you have to free the mem pointers in two places and you
don't get single-entry single-exit functions.
christian.bau said:Whose money is lost if you do shoddy work by following your
bosses orders? If it's your bosses money, go ahead. If it's not
your bosses money, follow your conscience.
CBFalconer said:Simply use: if (f) fclose(f);
(assuming no error test on fclose is needed).
Ben said:Isn't that what I said?
fclose(outfile) can be called with an uninitialized outfile in the
above. So besides protecting by detecting NULL value, you need to
initialized them to NULL.
Jack Klein said:You are laboring under a dangerous misunderstanding here.
Here is what C90 says about atoi(), atol(), and atof():
"The functions atof, atoi, and atol need not affect the value of the
integer expression errno on an error. If the value of the result
cannot be represented, the behavior is undefined."
The difference in C99 is that the new function atoll() is included:
"The functions atof, atoi, atol, and atoll need not affect the value
of the integer expression errno on an error. If the value of the
result cannot be represented, the behavior is undefined."
The ato... functions all invoke undefined behavior if the text string
represents a value outside the range of the function's return type. No
implementation-defined behavior or implementation-defined signal, just
plain old UB.
christian.bau said:The way the original poster described it, what you or I would
call "doing a proper job" is not what his boss calls "doing a
proper job". He would get blame and lose reputation much earlier,
and possibly his job as well.
Jack said:(e-mail address removed) wrote:
.... snip ...
You are laboring under a dangerous misunderstanding here.
Here is what C90 says about atoi(), atol(), and atof():
"The functions atof, atoi, and atol need not affect the value
of the integer expression errno on an error. If the value of
the result cannot be represented, the behavior is undefined."
The difference in C99 is that the new function atoll() is
included:
"The functions atof, atoi, atol, and atoll need not affect the
value of the integer expression errno on an error. If the
value of the result cannot be represented, the behavior is
undefined."
The ato... functions all invoke undefined behavior if the text
string represents a value outside the range of the function's
return type. No implementation-defined behavior or
implementation-defined signal, just plain old UB.
CBFalconer said:Jack Klein wrote: [...]The ato... functions all invoke undefined behavior if the text
string represents a value outside the range of the function's
return type. No implementation-defined behavior or
implementation-defined signal, just plain old UB.
I think you are missing the point.
Those ato* functions are only
present to allow old code to be compiled. There is no purpose
whatsoever to the atoll code except to encourage foolishness. They
can all be replaced by strto* calls, which have proper error
reporting capabilities, and should be so replaced in any new code.
You are laboring under a dangerous misunderstanding here.
Here is what C90 says about atoi(), atol(), and atof():
"The functions atof, atoi, and atol need not affect the value of the
integer expression errno on an error. If the value of the result
cannot be represented, the behavior is undefined."
The difference in C99 is that the new function atoll() is included:
"The functions atof, atoi, atol, and atoll need not affect the value
of the integer expression errno on an error. If the value of the
result cannot be represented, the behavior is undefined."
The ato... functions all invoke undefined behavior if the text string
represents a value outside the range of the function's return type. No
implementation-defined behavior or implementation-defined signal, just
plain old UB.
I couldn't see how it could be equivalent anyway, since this code is
valid
#include <stdlib.h>
...
#undef strtol
int i = atoi("42");
But it would break in an implementation where atoi is defined in terms
of strtol and strtol is a macro.
I see, thanks for this. Therefore atoi is certainly not equivalent to
(int)strtol(s, (char **)0, 10);
I couldn't see how it could be equivalent anyway, since this code is
valid
#include <stdlib.h>
...
#undef strtol
int i = atoi("42");
But it would break in an implementation where atoi is defined in terms
of strtol and strtol is a macro.
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.