473,473 Members | 2,039 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

strto[u]l and ERANGE

strtol and strtoul are defined as setting errno to ERANGE if they get
input representing a number too large or too small to represent in a
long or unsigned long (n869 7.20.1.4#8).

Does this mean that this (from n869 7.5):
--------
[#3] The value of errno is zero at program startup, but is
never set to zero by any library function.159) The value of
errno may be set to nonzero by a library function call
whether or not there is an error, provided the use of errno
^^^^^^^^^^^^^^^^^^^^^^^^^^
is not documented in the description of the function in this
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^
International Standard.
--------
prohibits strtol and friends from setting errno to ERANGE if their input
represents a value within the allowed range?

If they're allowed to set errno to ERANGE for any input, are there any
reasonable library implementations that actually do this, or would this
code still be safe to use?
--------
errno=0;
value=strtol(str,&endptr,10);
if(errno==ERANGE)
{
whine_and_handle_error("strtol set ERANGE");
}
if(endptr==str)
{
whine_and_handle_error("strtol couldn't find value");
}
/*Carry on...*/
--------
Or would I also need to check for value being one of the values that fgets
returned on out-of-range input? (In that case, is there any guaranteed
way to tell the difference between maximum-value and too-large?)
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
I have read all the pertinent "man" pages, sprinkled chicken blood on the
terminal, and uttered all the appropriate curses. So it is time to seek help
from a greater power. --Peter A. Buhr in uw.mfcf.gripe
Nov 15 '05 #1
16 1869
Dave Vandervies wrote:
strtol and strtoul are defined as setting errno to ERANGE if they get
input representing a number too large or too small to represent in a
long or unsigned long (n869 7.20.1.4#8).

Does this mean that this (from n869 7.5):
--------
[#3] The value of errno is zero at program startup, but is
never set to zero by any library function.159) The value of
errno may be set to nonzero by a library function call
whether or not there is an error, provided the use of errno
^^^^^^^^^^^^^^^^^^^^^^^^^^
is not documented in the description of the function in this
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^
International Standard.
--------
prohibits strtol and friends from setting errno to ERANGE if their input
represents a value within the allowed range?


Yes. Although there is a caveat with strtoul in that most
implementations
read the standard as accepting negative values. So input of '-1' would
produce UINT_MAX without setting errno.

% type strtoul.c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
unsigned u = strtoul("-1", 0, 10);
printf("%u [%d]\n", u, errno);
return 0;
}

% gcc -ansi -pedantic strtoul.c

% a.exe
4294967295 [0]

%

--
Peter

Nov 15 '05 #2
On Tue, 5 Jul 2005 22:25:06 +0000 (UTC), dj******@csclub.uwaterloo.ca
(Dave Vandervies) wrote in comp.lang.c:
strtol and strtoul are defined as setting errno to ERANGE if they get
input representing a number too large or too small to represent in a
long or unsigned long (n869 7.20.1.4#8).

Does this mean that this (from n869 7.5):
--------
[#3] The value of errno is zero at program startup, but is
never set to zero by any library function.159) The value of
errno may be set to nonzero by a library function call
whether or not there is an error, provided the use of errno
^^^^^^^^^^^^^^^^^^^^^^^^^^
is not documented in the description of the function in this
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^
International Standard.
--------
prohibits strtol and friends from setting errno to ERANGE if their input
represents a value within the allowed range?
Since the description of the function specifies under what conditions
it sets errno, it may not set it to any nonzero value under any other
condition. Since you read and highlighted the wording, and it is now
terribly complex or convoluted, why are you questioning it?
If they're allowed to set errno to ERANGE for any input, are there any
reasonable library implementations that actually do this, or would this
code still be safe to use?
--------
errno=0;
value=strtol(str,&endptr,10);
if(errno==ERANGE)
{
whine_and_handle_error("strtol set ERANGE");
}
if(endptr==str)
{
whine_and_handle_error("strtol couldn't find value");
}
/*Carry on...*/
--------
Or would I also need to check for value being one of the values that fgets
returned on out-of-range input? (In that case, is there any guaranteed
way to tell the difference between maximum-value and too-large?)


I have not got the faintest idea of what you mean about values fgets()
returns on out-of-range input, since fgets() has no concept of in
range or out of range.

Perhaps you should post again and reread your post a few times before
sending.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 15 '05 #3
Peter Nilsson <ai***@acay.com.au> wrote:
Yes. Although there is a caveat with strtoul in that most
implementations
read the standard as accepting negative values. So input of '-1' would
produce UINT_MAX without setting errno.


Is that correct? According to my reading of 7.20.1.4 (too long to quote)
in `strtoul("-1", 0, 10)', first "1" is converted
into a (mathematical) value `1'. Then, since there's
a "-", the value is negated (value `-1'). Then a check is made
if the value is representable (0..ULONG_MAX); it is clearly not,
so strtoul should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #4
Jack Klein <ja*******@spamcop.net> wrote:
On Tue, 5 Jul 2005 22:25:06 +0000 (UTC), dj******@csclub.uwaterloo.ca
(Dave Vandervies) wrote in comp.lang.c:

--------
errno=0;
value=strtol(str,&endptr,10);
if(errno==ERANGE)
{
whine_and_handle_error("strtol set ERANGE");
}
if(endptr==str)
{
whine_and_handle_error("strtol couldn't find value");
}
/*Carry on...*/
--------
Or would I also need to check for value being one of the values that fgets
returned on out-of-range input? (In that case, is there any guaranteed
way to tell the difference between maximum-value and too-large?)


I have not got the faintest idea of what you mean about values fgets()
returns on out-of-range input, since fgets() has no concept of in
range or out of range.


I think he meant to ask if one has to check strtol() for return
indicating and error, and then check `errno' (like with fgets(),
first you have to have to compare it against NULL, and *then* call
`ferror()' or `feof()'); or whether it's enough to check `errno'.
I think in case of strtol() it's only correct and enough to look
at the `errno' (for there're not many possibilities for an error).
Is that the case for all errno-setting functions, ie. do they *have*
*to* set `errno' to some non-zero value if an error occured?

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #5
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote in message
news:3j************@individual.net...
Peter Nilsson <ai***@acay.com.au> wrote:
Yes. Although there is a caveat with strtoul in that most
implementations
read the standard as accepting negative values. So input of '-1' would
produce UINT_MAX without setting errno.


Is that correct? According to my reading of 7.20.1.4 (too long to quote)
in `strtoul("-1", 0, 10)', first "1" is converted
into a (mathematical) value `1'. Then, since there's
a "-", the value is negated (value `-1'). Then a check is made
if the value is representable (0..ULONG_MAX); it is clearly not,
so strtoul should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?


Yep, the "it is clearly not" part. Negating an unsigned value
is well defined, since "unsigned" really means modulus arithmetic.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 15 '05 #6
P.J. Plauger wrote:
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote ...
[...] According to my reading of 7.20.1.4 (too long to quote)
in `strtoul("-1", 0, 10)', first "1" is converted
into a (mathematical) value `1'. Then, since there's
a "-", the value is negated (value `-1'). Then a check is made
if the value is representable (0..ULONG_MAX); it is clearly not,
so strtoul should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?


Yep, the "it is clearly not" part. Negating an unsigned value
is well defined, since "unsigned" really means modulus arithmetic.


Can we conclude that

strtoul("99999999999999999999999999999999999999999 "
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999",
NULL, 0)

.... is similarly well-defined, and should not report an out-of-
range error?

(I'm not being facetious; I'm looking for information.
The Standard's text seems foggy about such matters.)

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 15 '05 #7
"Eric Sosman" <es*****@acm-dot-org.invalid> wrote in message
news:b6********************@comcast.com...
P.J. Plauger wrote:
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote ...
[...] According to my reading of 7.20.1.4 (too long to quote)
in `strtoul("-1", 0, 10)', first "1" is converted
into a (mathematical) value `1'. Then, since there's
a "-", the value is negated (value `-1'). Then a check is made
if the value is representable (0..ULONG_MAX); it is clearly not,
so strtoul should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?


Yep, the "it is clearly not" part. Negating an unsigned value
is well defined, since "unsigned" really means modulus arithmetic.


Can we conclude that

strtoul("99999999999999999999999999999999999999999 "
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999",
NULL, 0)

... is similarly well-defined, and should not report an out-of-
range error?

(I'm not being facetious; I'm looking for information.
The Standard's text seems foggy about such matters.)


No. The converted value must be representable as a value
of the specified unsigned type. Negating a representable
value always yields a representable value; that was the
narrow point I was addressing.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 15 '05 #8
S.Tobias <si***@famous.bedbug.pals.invalid> wrote:

Is that correct? According to my reading of 7.20.1.4 (too long to quote)
in `strtoul("-1", 0, 10)', first "1" is converted
into a (mathematical) value `1'. Then, since there's
a "-", the value is negated (value `-1'). Then a check is made
if the value is representable (0..ULONG_MAX); it is clearly not,
so strtoul should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?


Yes -- the negation is in the return type, so for strtoul it's unsigned
negation. Thus, -1 becomes ULONG_MAX, which is in range.

-Larry Jones

You're going to be pretty lonely in the nursing home. -- Calvin
Nov 15 '05 #9
"P.J. Plauger" wrote:
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote in message
Peter Nilsson <ai***@acay.com.au> wrote:
Yes. Although there is a caveat with strtoul in that most
implementations read the standard as accepting negative values.
So input of '-1' would produce UINT_MAX without setting errno.


Is that correct? According to my reading of 7.20.1.4 (too long
to quote) in `strtoul("-1", 0, 10)', first "1" is converted into
a (mathematical) value `1'. Then, since there's a "-", the value
is negated (value `-1'). Then a check is made if the value is
representable (0..ULONG_MAX); it is clearly not, so strtoul
should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?


Yep, the "it is clearly not" part. Negating an unsigned value
is well defined, since "unsigned" really means modulus arithmetic.


I have had long bitter arguments about this (and been outshouted).
If we are going to perform modular transformations on the value
returned by strtoul, we should do it for all values, which includes
values beyond ULONG_MAX. I still consider the only sane mechanism
is to return ERANGE for anything beyond the _principal_ value
range. After that I would be willing to go along with the modular
conversion.

My attitude is that I want to know if the user is getting something
he doesn't expect.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #10
In article <42***************@yahoo.com>,
CBFalconer <cb********@worldnet.att.net> wrote:

My attitude is that I want to know if the user is getting something
he doesn't expect.


An approach I used (a long time ago) was to do a second conversion
back into a string, then do a strcmp-like thing to see if the value
made the round-trip intact. This is pretty simple for integers,
but floating point is a bit more difficult.
--
7842++
Nov 15 '05 #11
Anonymous 7843 wrote:
In article <42***************@yahoo.com>,
CBFalconer <cb********@worldnet.att.net> wrote:

My attitude is that I want to know if the user is getting something
he doesn't expect.
An approach I used (a long time ago) was to do a second conversion
back into a string, then do a strcmp-like thing to see if the value
made the round-trip intact.


Or you could just use sscanf:

(Range checking omitted)

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
unsigned u = 0;

if (argc < 2) {
fprintf(stderr, "no value provided\n");
exit(EXIT_FAILURE);
}

char *ptr = argv[1];

if (sscanf(ptr, "%u", &u) == 1) {
if (sscanf(ptr, "-%u", &u) == 1 && u)
puts("value is negative");
else
printf("value is %u\n", u);
} else
puts("invalid input");
return 0;
}

$ gcc -Wall -W -std=c99 -pedantic test_sscanf3.c -o test_sscanf3
$ ./test_sscanf3 "1"
value is 1
$ ./test_sscanf3 "-1"
value is negative
$ ./test_sscanf3 "-0"
value is 0
This is pretty simple for integers,
but floating point is a bit more difficult.


But since C doesn't have unsigned floating point types this isn't an
issue.

Robert Gamble

Nov 15 '05 #12
Robert Gamble wrote:
Anonymous 7843 wrote:
In article <42***************@yahoo.com>,
CBFalconer <cb********@worldnet.att.net> wrote:

My attitude is that I want to know if the user is getting something
he doesn't expect.


An approach I used (a long time ago) was to do a second conversion
back into a string, then do a strcmp-like thing to see if the value
made the round-trip intact.


Or you could just use sscanf:


The behaviour of the scanf family is undefined if the text being
converted is outside the range of the target type, even for unsigned
types. The strtoxxx functions on the other hand have a well defined
(if not always intuitively obvious) behaviour.

--
Peter

Nov 15 '05 #13
On 6 Jul 2005 18:32:35 -0700, "Robert Gamble" <rg*******@gmail.com>
wrote in comp.lang.c:
Anonymous 7843 wrote:
In article <42***************@yahoo.com>,
CBFalconer <cb********@worldnet.att.net> wrote:

My attitude is that I want to know if the user is getting something
he doesn't expect.


An approach I used (a long time ago) was to do a second conversion
back into a string, then do a strcmp-like thing to see if the value
made the round-trip intact.


Or you could just use sscanf:

(Range checking omitted)

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
unsigned u = 0;

if (argc < 2) {
fprintf(stderr, "no value provided\n");
exit(EXIT_FAILURE);
}

char *ptr = argv[1];

if (sscanf(ptr, "%u", &u) == 1) {
if (sscanf(ptr, "-%u", &u) == 1 && u)
puts("value is negative");
else
printf("value is %u\n", u);
} else
puts("invalid input");
return 0;
}

$ gcc -Wall -W -std=c99 -pedantic test_sscanf3.c -o test_sscanf3
$ ./test_sscanf3 "1"
value is 1
$ ./test_sscanf3 "-1"
value is negative
$ ./test_sscanf3 "-0"
value is 0
This is pretty simple for integers,
but floating point is a bit more difficult.


But since C doesn't have unsigned floating point types this isn't an
issue.

Robert Gamble


Except that scanf() and siblings, unlike strtoul() and siblings, does
produce undefined behavior on appropriately invalid input.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 15 '05 #14
Anonymous 7843 wrote:
CBFalconer <cb********@worldnet.att.net> wrote:

My attitude is that I want to know if the user is getting something
he doesn't expect.


An approach I used (a long time ago) was to do a second conversion
back into a string, then do a strcmp-like thing to see if the value
made the round-trip intact. This is pretty simple for integers,
but floating point is a bit more difficult.


Here is code I wrote some time ago to handle input from streams,
and catch all overflows.

/* ------------------------------------------------- *
* File txtinput.c *
* ------------------------------------------------- */

#include <limits.h> /* xxxx_MAX, xxxx_MIN */
#include <ctype.h> /* isdigit, isblank, isspace */
#include <stdio.h> /* FILE, getc, ungetc */
#include "txtinput.h"

#define UCHAR unsigned char

/* These stream input routines are written so that simple
* conditionals can be used:
*
* if (readxint(&myint, stdin)) {
* do_error_recovery; normally_abort_to_somewhere;
* }
* else {
* do_normal_things; usually_much_longer_than_bad_case;
* }
*
* They allow overflow detection, and permit other routines to
* detect the character that terminated a numerical field. No
* string storage is required, thus there is no limitation on
* the length of input fields. For example, a number entered
* with a string of 1000 leading zeroes will not annoy these.
*
* The numerical input routines *NEVER* absorb a terminal '\n'.
* Thus a sequence such as:
*
* err = readxint(&myint, stdin);
* flushln(stdin);
*
* will always consume complete lines.
*
* They are also re-entrant, subject to the limitations of file
* systems. e.g interrupting readxint(v, stdin) operation with
* a call to readxwd(wd, stdin) would not be well defined, if
* the same stdin is being used for both calls. If ungetc is
* interruptible the run-time system is broken.
*/

/*--------------------------------------------------------------
* Skip all blanks on f. At completion getc(f) will return
* a non-blank character, which may be \n or EOF
*
* Skipblks returns the char that getc will next return, or EOF.
*/
int skipblks(FILE *f)
{
int ch;

do {
ch = getc(f);
} while ((' ' == ch) || ('\t' == ch));
/* while (isblank((UCHAR)ch)); */ /* for C99 */
return ungetc(ch, f);
} /* skipblks */

/*--------------------------------------------------------------
* Skip all whitespace on f, including \n, \f, \v, \r. At
* completion getc(f) will return a non-blank character, which
* may be EOF
*
* Skipwhite returns the char that getc will next return, or EOF.
*/
int skipwhite(FILE *f)
{
int ch;

do {
ch = getc(f);
} while (isspace((UCHAR)ch));
return ungetc(ch, f);
} /* skipwhite */

/*--------------------------------------------------------------
* Read an unsigned value. Signal error for overflow or no
* valid number found. Returns true for error, false for noerror
*
* Skip all leading whitespace on f. At completion getc(f) will
* return the character terminating the number, which may be \n
* or EOF among others. Barring EOF it will NOT be a digit. The
* combination of error and the following getc returning \n
* indicates that no numerical value was found on the line.
*
* If the user wants to skip all leading white space including
* \n, \f, \v, \r, he should first call "skipwhite(f);"
*
* Peculiarity: This specifically forbids a leading '+' or '-'.
* Peculiarity: This forbids overflow, unlike C unsigned usage.
* on overflow, UINT_MAX is returned.
*/
int readxwd(unsigned int *wd, FILE *f)
{
unsigned int value, digit;
int status;
int ch;

#define UWARNLVL (UINT_MAX / 10U)
#define UWARNDIG (UINT_MAX - UWARNLVL * 10U)

value = 0; /* default */
status = 1; /* default error */

do {
ch = getc(f);
} while ((' ' == ch) || ('\t' == ch)); /* skipblanks */
/* while (isblank((UCHAR)ch)); */ /* for C99 */

if (!(EOF == ch)) {
if (isdigit((UCHAR)ch)) /* digit, no error */
status = 0;
while (isdigit((UCHAR)ch)) {
digit = (unsigned) (ch - '0');
if ((value < UWARNLVL) ||
((UWARNLVL == value) && (UWARNDIG >= digit)))
value = 10 * value + digit;
else { /* overflow */
status = 1;
value = UINT_MAX;
}
ch = getc(f);
} /* while (ch is a digit) */
}
*wd = value;
ungetc(ch, f);
return status;
} /* readxwd */

/*--------------------------------------------------------------
* Read a signed value. Signal error for overflow or no valid
* number found. Returns true for error, false for noerror. On
* overflow either INT_MAX or INT_MIN is returned in *val.
*
* Skip all leading whitespace on f. At completion getc(f) will
* return the character terminating the number, which may be \n
* or EOF among others. Barring EOF it will NOT be a digit. The
* combination of error and the following getc returning \n
* indicates that no numerical value was found on the line.
*
* If the user wants to skip all leading white space including
* \n, \f, \v, \r, he should first call "skipwhite(f);"
*
* Peculiarity: an isolated leading '+' or '-' NOT immediately
* followed by a digit will return error and a value of 0, when
* the next getc will return that following non-digit. This is
* caused by the single level ungetc available.
*/
int readxint(int *val, FILE *f)
{
unsigned int value;
int status, negative;
int ch;

*val = value = 0; /* default */
status = 1; /* default error */
negative = 0;

do {
ch = getc(f);
} while ((' ' == ch) || ('\t' == ch)); /* skipwhite */
/* while (isblank((UCHAR)ch)); */ /* for C99 */

if (!(EOF == ch)) {
if (('+' == ch) || ('-' == ch)) {
negative = ('-' == ch);
ch = getc(f); /* absorb any sign */
}

if (isdigit((UCHAR)ch)) { /* digit, no error */
ungetc(ch, f);
status = readxwd(&value, f);
ch = getc(f); /* This terminated readxwd */
}

if (negative && (value < UINT_MAX) &&
((value - 1) <= -(1 + INT_MIN))) *val = -value;
else if (value <= INT_MAX) *val = value;
else { /* overflow */
status = 1;
if (value)
if (negative) *val = INT_MIN;
else *val = INT_MAX;
}
}
ungetc(ch, f);
return status;
} /* readxint */

/*-----------------------------------------------------
* Flush input through an end-of-line marker inclusive.
*/
int flushln(FILE *f)
{
int ch;

do {
ch = getc(f);
} while (('\n' != ch) && (EOF != ch));
return ch;
} /* flushln */

/* End of txtinput.c */

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #15
P.J. Plauger <pj*@dinkumware.com> wrote:
"Eric Sosman" <es*****@acm-dot-org.invalid> wrote in message
news:b6********************@comcast.com...
P.J. Plauger wrote:
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote ... [...] According to my reading of 7.20.1.4 (too long to quote)
in `strtoul("-1", 0, 10)', first "1" is converted
into a (mathematical) value `1'. Then, since there's
a "-", the value is negated (value `-1'). Then a check is made
if the value is representable (0..ULONG_MAX); it is clearly not,
so strtoul should return ULONG_MAX and set `errno' to ERANGE.
Have I got something wrong?

Yep, the "it is clearly not" part. Negating an unsigned value
is well defined, since "unsigned" really means modulus arithmetic.


Can we conclude that

strtoul("99999999999999999999999999999999999999999 "
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999",
NULL, 0)

... is similarly well-defined, and should not report an out-of-
range error?

(I'm not being facetious; I'm looking for information.
The Standard's text seems foggy about such matters.)


No. The converted value must be representable as a value
of the specified unsigned type. Negating a representable
value always yields a representable value; that was the
narrow point I was addressing.


Although I agree this is a reasonable interpretation, I think
the Standard is not quite clear about it. It doesn't actually
say that the intermediate value is range-checked *before* negation
(or that it has a type; it only says "the value [...] is negated
(in the return type)").

I think one could argue that this:

strtoul("-99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999",
NULL, 10)

should return some valid, non-error result.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #16
S.Tobias wrote:
Jack Klein <ja*******@spamcop.net> wrote:
(Dave Vandervies) wrote in comp.lang.c:
--------
errno=0;
value=strtol(str,&endptr,10);
if(errno==ERANGE)
{
whine_and_handle_error("strtol set ERANGE");
}
if(endptr==str)
{
whine_and_handle_error("strtol couldn't find value");
}
/*Carry on...*/
--------
Or would I also need to check for value being one of the values that
fgets returned on out-of-range input? (In that case, is there any
guaranteed way to tell the difference between maximum-value and too-
large?)
I have not got the faintest idea of what you mean about values fgets()
returns on out-of-range input, since fgets() has no concept of in
range or out of range.


I think he meant to ask if one has to check strtol() for return
indicating and error, and then check `errno' (like with fgets(),
first you have to have to compare it against NULL, and *then* call
`ferror()' or `feof()'); or whether it's enough to check `errno'.
I think in case of strtol() it's only correct and enough to look
at the `errno' (for there're not many possibilities for an error).


You still need to be careful with input like, e.g. "", "-", "x" where
errno will not be set.
Is that the case for all errno-setting functions, ie. do they *have*
*to* set `errno' to some non-zero value if an error occured?


Yes, but only for the documented conditions [error is a bit of a
misnomer, as the above samples should show.]

Only non 'errno-setting functions' have freedom to do otherwise...

7.5p3
The value of errno may be set to nonzero by a library function call
whether or not there is an error, provided the use of errno is not
documented in the description of the function in this International
Standard.

--
Peter

Nov 15 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: William Payne | last post by:
Hello, I am in the process of converting a C++ program to a C program. The user of the program is supposed to supply an integer on the command line and in the C++ version of the program I was using...
11
by: nrk | last post by:
Isn't: char s = "--4"; char *endptr; strtol(s, &endptr, 0); supposed to return 0 and set endptr to s? I have run into an implementation (not gcc, gcc does what I expect) that is returning...
29
by: RoSsIaCrIiLoIA | last post by:
write the function int readINT(FILE* fp); that read an int from fp and return it. given the following conditions a. Do not use arrays b. Do not use any comparison function like if/then or...
15
by: Anonymousgoogledeja | last post by:
Hi all, since the function atof, atoi, _atoi64, atol returned value are Return Values Each function returns the double, int, __int64 or long value produced by interpreting the input...
18
by: pete | last post by:
On my system, the following five expressions are true: (HUGE_VAL == HUGE_VAL / 2) (1 / HUGE_VAL == 0) (sqrt(HUGE_VAL) == HUGE_VAL) (sqrt(-1) == HUGE_VAL) (sqrt(-HUGE_VAL) == HUGE_VAL) and
6
by: vickie | last post by:
I have a sql server7 database using C#. The system runs fine until the user try to run a report. I get the following error: Object reference not set to an instance of an object. Description: An...
15
by: AmmarN | last post by:
Hi all, I have a c++ programme that intakes a binary file and performs various operations on it. I am not gonna get in to the details of the operations, currently i specify the order in which the...
105
by: Keith Thompson | last post by:
pereges <Broli00@gmail.comwrites: These types already have perfectly good names already. Why give them new ones? If you must rename them for some reason, use typedefs, not macros. --
28
by: pereges | last post by:
Hi I've a string input and I have to parse it in such a way that that there can be only white space till a digit is reached and once a digit is reached, there can be only digits or white space till...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.