Reputation: 927
Traditional strtol()
is usually used like this:
int main()
{
errno = 0;
char *s = "12345678912345678900";
char *endptr;
long i = strtol(s, &endptr, 10);
if(i == LONG_MAX && errno == ERANGE)
printf("overflow");
}
We need to access errno
two times, and errno
nowadays is usually a C macro finally expanded to a function. It seems a little expensive considering parsing string to integer isn't a heavy job.
So, is it better to implement strtol
without errno
but using some other ways to indicating overflow?
like:
long strtol(const char *nptr, char **endptr, int base, bool *is_overflow);
instead of
long strtol(const char *nptr, char **endptr, int base);
Upvotes: 2
Views: 754
Reputation: 28830
There is actually some overhead besides errno
in strtol()
, like skipping spaces, taking care of the base (10 or hexa), check characters ...
In a specific environment where speed is critical and you know the string provided is a number base 10 that fits in a long
, you could make your own quick function, like
#include <ctype.h>
long mystrtol(char *s) {
long res = 0, minus = *s == '-';
if (minus || *s == '+') s++;
while (isdigit(*s)) {
res = res*10 + (*s++ - '0');
}
return minus ? -res : res;
}
and choose to inline it.
Upvotes: 0
Reputation: 153338
is it better to implement strtol without errno ...
No.
... but using some other ways to indicating overflow?
No.
long int strtol(const char * restrict nptr, char ** restrict endptr, int base);
strtol()
is a standard C library function and any implementation must adhere to proper use of the 3 inputs and errno
to be compliant.
Of course OP can implement some other my_strtol()
as desired.
Any performance concerns around avoiding errno
are a micro-optimization yet a reasonable design goal.
It really comes down to how to conveys problems of string to long
Overflow "12345678912345678901234567890"
No conversions "abc"
Excess junk "123 abc"
Leading space allowed, trailing space allowed?
Allow various bases?
Once functionality about all exceptional cases are defined, not just overflow, then coding concerns about errno
is useful, even if unlikely to make any meaningful performance improvements.
IMO, coding to one base only is likely a more productive path to speed improvements than errno
.
OP code is not a robust strtol()
usage. Suggest:
char *s = "12345678912345678900";
char *endptr;
errno = 0;
long i = strtol(s, &endptr, 10);
if (errno == ERANGE) printf("Overflow %ld\n", i);
else if (s == endptr) printf("No conversion %ld\n", i);
else if (*endptr) printf("Extra Junk %ld\n", i);
else printf("Success %ld\n", i);
Upvotes: 4