strtol question

R

Richard Bos

nrk said:
Isn't:

char s[] = "--4";
char *endptr;

strtol(s, &endptr, 0);

supposed to return 0 and set endptr to s?
Yes.

I have run into an implementation
(not gcc, gcc does what I expect) that is returning LONG_MIN!!

That's only allowed if the converted value _is_ LONG_MIN, or is outside
the range of long and negative. In this case, there is no converted
value, since neither "--4" nor "-4" starts with an integer constant.
I am afraid to see what it did to endptr :)

I'm _curious_ to see what it did... Which implementation is this, btw?

Richard
 
N

nrk

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 LONG_MIN!! I am afraid
to see what it did to endptr :)

-nrk.
 
R

Richard Bos

Tom St Denis said:
The third value is supposed to be the base you want it converted in. The
man pages on my distro say that it can return LONG_MIN if the value
underflows and it will set errno. So maybe a base-0 request is an
underflow?

Or maybe not. And maybe it's better to read the Standard before making
wild-asses wrong guesses in public. If you had done so, you'd have known
that a base of 0 is a perfectly well defined request to the
implementation to figure out the base from the string itself.

Richard
 
T

Tom St Denis

nrk said:
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 LONG_MIN!! I am afraid
to see what it did to endptr :)

The third value is supposed to be the base you want it converted in. The
man pages on my distro say that it can return LONG_MIN if the value
underflows and it will set errno. So maybe a base-0 request is an
underflow?

Tom
 
D

Darrell Grainger

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 LONG_MIN!! I am afraid
to see what it did to endptr :)

That seems broken to me. For base 0 and 2 to 36 the standard indicates,

optionally preceded by a plus or minus sign.

Not one or more plus and minus signs but *A*, single, plus or minus sign.

It seems that your implementation is assuming that --4 is a valid number
outside the range of representable values. This is why it is returning
LONG_MIN. It is probably setting errno to ERANGE as well.
 
D

Dan Pop

In said:
Isn't:

char s[] = "--4";
char *endptr;

strtol(s, &endptr, 0);

supposed to return 0 and set endptr to s?
Yes.

I have run into an implementation (not gcc, gcc does what I expect)

gcc has exactly zilch to do with your problem: it's only a compiler, not
a full implementation, and strtol() is a library function.
that is returning LONG_MIN!!

That implementation thinks that the correct result of converting "--4"
is outside the range of long. Check if errno is set to ERANGE, too.
I am afraid to see what it did to endptr :)

Have a look, anyway.

Dan
 
N

nrk

Dan said:
In <[email protected]> nrk
Isn't:

char s[] = "--4";
char *endptr;

strtol(s, &endptr, 0);

supposed to return 0 and set endptr to s?
Yes.

I have run into an implementation (not gcc, gcc does what I expect)

gcc has exactly zilch to do with your problem: it's only a compiler, not
a full implementation, and strtol() is a library function.

Sorry. That was sloppy on my part. I should've said glibc.
That implementation thinks that the correct result of converting "--4"
is outside the range of long. Check if errno is set to ERANGE, too.

Yes, it sets errno to ERANGE under this situation [*].
Have a look, anyway.
It consumes characters in the string like a regular strtol conversion and
sets endptr to the first non-digit encountered after that.

The implementation under question is the Intel C++ compiler suite v8.0.055
(invoked as a C compiler) under Linux

The behavior is truly bizzare. I have a nagging feeling that this
implementation is using the fact that integer overflow results in wrap
around (no harm in that, as the implementation very well knows this is the
case). Here's what it does:

"--123" : Returns LONG_MIN and sets errno to ERANGE
"-+123" : Returns -123 and errno is not set
"+-123" : Returns LONG_MAX and sets errno to ERANGE
"++123" : Returns 123 and errno is not set.

So far so good. But look what happens:

LONG_MIN = -2147483648, LONG_MAX = 2147483647

"--2147483647" : Returns LONG_MIN and sets errno to ERANGE
"--2147483648" : Returns LONG_MIN and errno is not set!!
"--2147483649" : Returns LONG_MIN + 1 and errno is not set!!

"-+2147483647" : Returns -LONG_MAX and errno is not set!!
"-+2147483648" : Returns LONG_MIN and errno is not set!!
"-+2147483649" : Returns LONG_MIN and sets errno to ERANGE

"+-2147483647" : Returns LONG_MAX and sets errno to ERANGE
"+-2147483648" : Returns LONG_MAX and sets errno to ERANGE
"+-2147483649" : Returns LONG_MAX and errno is not set!!

"--2147483647" : Returns LONG_MIN and sets errno to ERANGE
"--2147483648" : Returns LONG_MIN and errno is not set!!
"--2147483649" : Returns LONG_MIN + 1 and errno is not set!!

Even accounting for overflow, underflow and wrap-arounds, I am not able to
fully explain all those results.

Who was that who said "This is not correct. This is not even wrong!" again?
:)

I posted a message on their public forums, but if someone has Intel Premier
support and experience this issue, I encourage you to file a bug report
with them through your premier support as well.

-nrk.
 
N

nrk

Richard said:
nrk said:
Isn't:

char s[] = "--4";
char *endptr;

strtol(s, &endptr, 0);

supposed to return 0 and set endptr to s?
Yes.

I have run into an implementation
(not gcc, gcc does what I expect) that is returning LONG_MIN!!

That's only allowed if the converted value _is_ LONG_MIN, or is outside
the range of long and negative. In this case, there is no converted
value, since neither "--4" nor "-4" starts with an integer constant.
I am afraid to see what it did to endptr :)

I'm _curious_ to see what it did... Which implementation is this, btw?

It consumes characters like a regular call to strtol. The implementation is
Intel's C++ compiler suite (invoked as a C compiler) v8.0.055 under Linux.
See my response to Dan for more gory details.

-nrk.
 
M

Mark Shelor

Richard said:
Or maybe not. And maybe it's better to read the Standard before making
wild-asses wrong guesses in public.


WHACK! goes the ruler. Woe to him who doesn't first consult (drum roll
please) THE STANDARD.

Don't feel bad, Tom. It looks like the compiler library vendor didn't
read the standard either. Let's hope for the OP's sake that
it's just a bug in strtol(), rather than the lexical scanner's inability
to correctly parse an integer constant ;)

Mark
 
M

Martin Ambuhl

nrk said:
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
LONG_MIN!! I am afraid to see what it did to endptr :)

There is nothing to fear, just inspect the damn thing:

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

int main(void)
{
char s[] = "--4";
char sx[] = "-4";
char *endptr;
long t, tx;

t = strtol(s, &endptr, 0);
printf("\"%s\" is at %p,\n"
"strtol returns %ld and enptr points to %p\n",
s, (void *) s, t, (void *) endptr);
tx = strtol(sx, &endptr, 0);
printf("\"%s\" is at %p,\n"
"strtol returns %ld and enptr points to %p\n",
sx, (void *) sx, tx, (void *) endptr);
return 0;
}



"--4" is at effc0,
strtol returns 0 and enptr points to effc0
"-4" is at effc8,
strtol returns -4 and enptr points to effca
 
N

nrk

Martin said:
nrk said:
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
LONG_MIN!! I am afraid to see what it did to endptr :)

There is nothing to fear, just inspect the damn thing:

Ahhhh!!! Famous last words before the buggy implementation was run on a DS9K
:) FWIW, I did inspect endptr and you can see the results elsethread.

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

int main(void)
{
char s[] = "--4";
char sx[] = "-4";
char *endptr;
long t, tx;

t = strtol(s, &endptr, 0);
printf("\"%s\" is at %p,\n"
"strtol returns %ld and enptr points to %p\n",
s, (void *) s, t, (void *) endptr);
tx = strtol(sx, &endptr, 0);
printf("\"%s\" is at %p,\n"
"strtol returns %ld and enptr points to %p\n",
sx, (void *) sx, tx, (void *) endptr);
return 0;
}



"--4" is at effc0,
strtol returns 0 and enptr points to effc0
"-4" is at effc8,
strtol returns -4 and enptr points to effca
 
R

Richard Bos

Mark Shelor said:
WHACK! goes the ruler. Woe to him who doesn't first consult (drum roll
please) THE STANDARD.

Indeed. Or, in fact, a basic C textbook, or his compiler helpfiles, or
his man pages. Any of those would have corrected his very basic error,
so that he could have learned something instead of spreading what is
simply faulty information on Usenet.

I don't give a duck's arse whether Tom consults the Standard or K&R or
his class notes, as long as he doesn't spread misinformation.
Don't feel bad, Tom. It looks like the compiler library vendor didn't
read the standard either.

Yes. Which just might make him liable for damages, because he didn't
deliver what he sold: a C implementation.

Richard
 

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

Similar Threads

string to int 5
strtol() 1
Scanf is being prioritized over printf ? 1
Strtol vs sscanf 3
Sufficient error checking of strtol()? 5
detabbing again 105
Scipy install Problems 1
question about va_list 1

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top