strtol library function

D

David Scarlett

Another two questions...

Is behaviour defined when the first argument of strtol is NULL?

And if the string contains only digits, is the 2nd argument (assuming
it wasn't NULL) guaranteed to be set to a pointer to a pointer to '\0'?


Thanks.
 
P

P.J. Plauger

Another two questions...

Is behaviour defined when the first argument of strtol is NULL?
No.

And if the string contains only digits, is the 2nd argument (assuming
it wasn't NULL) guaranteed to be set to a pointer to a pointer to '\0'?

The second argument is passed by value as a pointer to pointer. It makes
no sense to talke about what it might get set to. But the pointer it
points at on a successful return should designate the terminating NUL,
in the case you describe. I think that's what you really meant.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
A

Al Bowers

David said:
Another two questions...

Is behaviour defined when the first argument of strtol is NULL?

The first agrument must be a value that represents a pointer to
a string. A value of NULL is not defined for the function.

I have a question regarding errno. Given the following code, which
simply detects if there was a proper coversion or not, is the test
using LONG_MIN or LONG_MAX neccessary or can one use use the test
errno == ERANGE?

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

int main(void)
{
char *str = "-123456789999999999999", *s;
long num = 0;

errno = 0;
num = strtol(str,&s,10);
if(s == str || *s != '\0' ||
((errno == ERANGE) && (num == LONG_MAX || num == LONG_MIN)))
printf("\"%s\" does not convert to a long value\n",str);
else
printf("\"%s\" = %ld\n",str,num);
return 0;
}
 
P

P.J. Plauger

I have a question regarding errno. Given the following code, which
simply detects if there was a proper coversion or not, is the test
using LONG_MIN or LONG_MAX neccessary or can one use use the test
errno == ERANGE?

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

int main(void)
{
char *str = "-123456789999999999999", *s;
long num = 0;

errno = 0;
num = strtol(str,&s,10);
if(s == str || *s != '\0' ||
((errno == ERANGE) && (num == LONG_MAX || num == LONG_MIN)))
printf("\"%s\" does not convert to a long value\n",str);
else
printf("\"%s\" = %ld\n",str,num);
return 0;
}

The test of errno should suffice.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
A

Al Bowers

P.J. Plauger said:
The test of errno should suffice.

Yeah! That is the way I always used it. But recently someone mentioned
that there is nothing to prevent the a function implementation from
setting errno to ERANGE even if the resulting value is in the range
of a long. I looked at the Standard's description of the function and
saw that it id say the an unrepresentable value would result in both
errno == ERANGE and the return value either LONG_MAX or LONG_MIN.
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
Is behaviour defined when the first argument of strtol is NULL?

No.
And if the string contains only digits, is the 2nd argument (assuming
it wasn't NULL) guaranteed to be set to a pointer to a pointer to '\0'?

The argument is unchanged. It's the pointed value that is changed to a
pointer to '\0'.
 
J

jacob navia

Paul Emmons said:
[snip]

It still seems rather strange to me that strtoul() accepts "-2" and
returns 4294967294 without complaint, but according to the man page it
is supposed to do so.

But HOW is that function supposed to know that
it was passed -2 and NOT 4294967294 ????

The binary representation of both is exactly the same!
 
P

Paul Emmons

Yeah! That is the way I always used it. But recently someone mentioned
that there is nothing to prevent the a function implementation from
setting errno to ERANGE even if the resulting value is in the range
of a long. I looked at the Standard's description of the function and
saw that it id say the an unrepresentable value would result in both
errno == ERANGE and the return value either LONG_MAX or LONG_MIN.

Perhaps that was in the course of my stupid question about strtoul(),
which I erroneously claimed that it returned ERANGE for input between
LONG_MAX and ULONG_MAX. It doesn't. I was actually playing with
strtol() instead, and didn't realize it.

It still seems rather strange to me that strtoul() accepts "-2" and
returns 4294967294 without complaint, but according to the man page it
is supposed to do so.
 
B

Ben Pfaff

jacob navia said:
Paul Emmons said:
[snip]

It still seems rather strange to me that strtoul() accepts "-2" and
returns 4294967294 without complaint, but according to the man page it
is supposed to do so.

But HOW is that function supposed to know that
it was passed -2 and NOT 4294967294 ????

Because the first character of the string passed to it, following
whitespace is '-', or some locale-specific version thereof.
The binary representation of both is exactly the same!

Their text representations differ.

Perhaps you should join Richard Heathfield's "reading for
comprehension" class.
 
T

those who know me have no need of my name

in comp.lang.c i read:
It still seems rather strange to me that strtoul() accepts "-2" and
returns 4294967294 without complaint, but according to the man page it
is supposed to do so.

for the same reason that assigning -2 to an unsigned long results in that
value.
 
D

Dan Pop

In said:
It still seems rather strange to me that strtoul() accepts "-2" and
returns 4294967294 without complaint, but according to the man page it
is supposed to do so.

According to my reading of the C standard it isn't supposed to do so:

Returns

8 The strtol, strtoll, strtoul, and strtoull functions return
the converted value, if any. If no conversion could be performed,
zero is returned. If the correct value is outside the range of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
^^^^^^^^^^^^^^^^^^^^
ULONG_MAX, or ULLONG_MAX is returned (according to the return
type and sign of the value, if any), and the value of the macro
ERANGE is stored in errno.

Unless I'm missing something, -2 is outside the range of values that can
be represented by unsigned long. And any argument about "folding" it into
range would equally apply to values above ULONG_MAX, so this function
should NEVER set errno to ERANGE if that argument applied.

However, I know, from past discussions, that committee members disagree
with my interpretation.

Dan
 
D

Dan Pop

In said:
in comp.lang.c i read:


for the same reason that assigning -2 to an unsigned long results in that
value.

If it's the same reason, then when should strtoul() set errno to ERANGE
and why?

Dan
 
A

Al Bowers

Dan said:
According to my reading of the C standard it isn't supposed to do so:

Returns

8 The strtol, strtoll, strtoul, and strtoull functions return
the converted value, if any. If no conversion could be performed,
zero is returned. If the correct value is outside the range of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
^^^^^^^^^^^^^^^^^^^^
ULONG_MAX, or ULLONG_MAX is returned (according to the return
type and sign of the value, if any), and the value of the macro
ERANGE is stored in errno.

Unless I'm missing something, -2 is outside the range of values that can
be represented by unsigned long. And any argument about "folding" it into
range would equally apply to values above ULONG_MAX, so this function
should NEVER set errno to ERANGE if that argument applied.

I don't have the previous standard available but I believe the wording
for the description for strtoul was "If the subject sequence field
begins witha a minus sign, the value resulting from the conversion is
negated". Thus the function would first convert "-2" to, for example,
unsigned long x = 2, then it would be negated, x = -x. I can accept that
but I don't see this wording in the current standard, which, at least to
me, is confusing.

On a related issue, the current standard seems to support symmetry
between functions *scanf's and strotol, at least in regards to the
format of the expected subject sequence, yet doesn't show any support
for the symmetry in the resulting value. Most of the implementions that
I use, sscanf and strtoul will yield different results for the string
sequence "-2".
 
A

Al Bowers

Al Bowers wrote:

On a related issue, the current standard seems to support symmetry
between functions *scanf's and strotol, at least in regards to the
format of the expected subject sequence, yet doesn't show any support
for the symmetry in the resulting value. Most of the implementions that
I use, sscanf and strtoul will yield different results for the string
sequence "-2".

Oops, I meant "will yield a different result for the string
"4294967297", where the results are 4294967295 (ULONG_MAX) with
strtoul and 1 with sscanf.
 
C

CBFalconer

Dan said:
.... snip ...

Unless I'm missing something, -2 is outside the range of values
that can be represented by unsigned long. And any argument about
"folding" it into range would equally apply to values above
ULONG_MAX, so this function should NEVER set errno to ERANGE if
that argument applied.

We had this argument right here and on comp.std.c a month or so
ago, and I took your side. I started it when I found that the
DJGPP implementation of strtoul did that quiet conversion. At any
rate, I got outshouted, and beaten into agreement that the action
was required by the standard.

I still think it is wrong, wrong, wrong, in fact wrong.
 
T

those who know me have no need of my name

[fu-t set]

in comp.lang.c i read:
If it's the same reason, then when should strtoul() set errno to ERANGE
and why?

given how negative values are handled with unsigned types and the rationale
provided for strtoul's addition i would say there is no reason it should,
despite wording which allows it.

i can envision a rationale for setting ERANGE and forcing ULONG_MAX as the
result -- when the magnitude of the value is outside 0..ULONG_MAX, or when
prefixed with a minus sign / dash outside of LONG_MIN..LONG_MAX -- but
that's just me thinking of convenience and doesn't come quickly to mind
from a plain reading of the standard.
 
D

Dan Pop

Oops, I meant "will yield a different result for the string
"4294967297", where the results are 4294967295 (ULONG_MAX) with
strtoul and 1 with sscanf.

In the case of sscanf, you're invoking undefined behaviour.

Dan
 

Ask a Question

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.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top