errno


B

Bill Cunningham

My little utility doesn't print an errno value like it should. I have
tried to fix it but have failed. I've never really used errno.h but always
perror() so what am I doing wrong here.

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
if ((a = strtol(argv[1], NULL, 16)) == -1)
printf("%s\n", strerror(errno));
printf("%d\n", a);
return 0;
}
 
Ad

Advertisements

E

Eric Wolf

First:

The line
printf("%d\n", a);

seems to be wrong. As a is long int, it should read

printf("%ld\n", a);
^ mind the 'l'

Second:

As I understand 'man strtol' on my system, strtol sets errno only in
case of underflow or overflow, in which case it returns LONG_MIN or
respectively LONG_MAX.

So checking for -1 doesn't detect an error situation. You should
check for LONG_MAX and errno != 0 and LONG_MIN and errno != 0, or
simply errno != 0.

Posix manpage 'man 3posix strtol' on my system, says also a return value
of 0 could indicate an error if errno != 0 additionally.

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
a = strtol(argv[1], NULL, 16);
if (errno != 0)
printf("%s\n", strerror(errno));
printf("%ld\n", a);
return 0;
}

Should print

Numerical result out of range
9223372036854775807

for in input of
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

Eric
 
B

Bill Cunningham

Eric Wolf said:
First:

The line


seems to be wrong. As a is long int, it should read

printf("%ld\n", a);
^ mind the 'l'

Never really used long int either much.
Usually go to atoi().
Second:

As I understand 'man strtol' on my system, strtol sets errno only in
case of underflow or overflow, in which case it returns LONG_MIN or
respectively LONG_MAX.

So checking for -1 doesn't detect an error situation. You should
check for LONG_MAX and errno != 0 and LONG_MIN and errno != 0, or
simply errno != 0.

Posix manpage 'man 3posix strtol' on my system, says also a return value
of 0 could indicate an error if errno != 0 additionally.

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
a = strtol(argv[1], NULL, 16);
if (errno != 0)
printf("%s\n", strerror(errno));
printf("%ld\n", a);
return 0;
}

Should print

Numerical result out of range
9223372036854775807

for in input of
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

Eric

Thanks much! I typed

/h2d fffffffffffffff
And all that was printed was -1. I'm used to thinking that's an error but
there is those few weird functions...

Bill
 
I

Ike Naar

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
a = strtol(argv[1], NULL, 16);
if (errno != 0)
printf("%s\n", strerror(errno));
printf("%ld\n", a);
return 0;
}
Thanks much! I typed

/h2d fffffffffffffff
And all that was printed was -1. I'm used to thinking that's an error but
there is those few weird functions...

That is why you should have used "%ld" instead of "%d" to
print the value of a. Had you used "%ld", the output would
not have been -1 but the equivalent of LONG_MAX.
 
B

Bill Cunningham

That is why you should have used "%ld" instead of "%d" to
print the value of a. Had you used "%ld", the output would
not have been -1 but the equivalent of LONG_MAX.

Got it now. All I have really used was atoi and it doesn't return error.
I might just go to errno.h instead of simple perror().

Bill
 
B

Barry Schwarz

My little utility doesn't print an errno value like it should. I have

Nowhere in your code do you attempt to print the value of errno.
tried to fix it but have failed. I've never really used errno.h but always
perror() so what am I doing wrong here.

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
if ((a = strtol(argv[1], NULL, 16)) == -1)

According to your follow-up message, argv[1] is a string consisting of
15 f's. Under what conditions do you think this would ever produce a
value of -1? (You should read the description of strtol and determine
the only situation when it can produce a negative value.)

What is the size of long int on your system? How did you determine
this?
printf("%s\n", strerror(errno));

What makes you think errno was set by anything your program did?
printf("%d\n", a);

This undefined behavior has been addressed by others.
 
Ad

Advertisements

B

Bill Cunningham

Barry Schwarz said:
My little utility doesn't print an errno value like it should. I have

Nowhere in your code do you attempt to print the value of errno.
tried to fix it but have failed. I've never really used errno.h but always
perror() so what am I doing wrong here.

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
if ((a = strtol(argv[1], NULL, 16)) == -1)

According to your follow-up message, argv[1] is a string consisting of
15 f's. Under what conditions do you think this would ever produce a
value of -1? (You should read the description of strtol and determine
the only situation when it can produce a negative value.)

What is the size of long int on your system? How did you determine
this?
printf("%s\n", strerror(errno));

What makes you think errno was set by anything your program did?
printf("%d\n", a);

This undefined behavior has been addressed by others.
return 0;
}

Works fine now. I've never used strtol or strtoll. I have occasssionally
used strtod and had great success. errno seems to set to ERANGE now when I
intentionally try to over or underflow. I am in the habit of -1 as in most
*nix sys calls being an error. I admit I should've look closer at the man
page.

Bill
 
B

Bill Cunningham

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

int main(int argc, char *argv[])
{
long int a;
errno = 0;
if ((a = strtol(argv[1], NULL, 16)) != 0)
printf("%s\n", strerror(errno));
printf("%ld\n", a);
return 0;
}

Works as it appears anyway. Who knows what subtle bug might be lurking.
 
Ad

Advertisements

B

Bill Cunningham

Barry Schwarz said:
What is the size of long int on your system?
[...]

Oh yeah ok sorry. Looks like a long and long long are 64 bits while an int
is 32 bit.

Bill
 

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


Top