Is the functions stricmp()
and strnicmp()
removed in C99?
I always get warning implicit declaration of funtion stricmp() (and also strnicmp() ) when I try to compile it against C99.
For example, the simple code below get me that warning.
#include<string.h>
#include<stdio.h>
char arr[100]="hello";
char arr2[100]="hEllo";
int main()
{
int n=-1;
printf("%d\n",n);
n=strnicmp(arr,arr2,3); // the same when use the function stricmp();
printf("%d\n",n);
getchar();
return 0;
}
When I try to compile this piece of code against C99(gcc -Wall -std=c99 main.c -o main
), I get that warning. But when I compile it without the -std=c99
, no warning will be thrown.
However, even though there is warning of implicit declaration, my code still work out right.
Why is that? Is that a bug? If not a bug, then what is exactly the change of C99 which make that warning happen?
When code compiles with C99, it conform to the C99 standard, which does not have stricmp()
. When code compile without C99 switch, it conforms to an unknown standard that implements stricmp()
. (Given gcc
without -std=c99
, likely compiles to the C89/90 standard wihich allows implicit declarations.)
As @Joachim Pileborg commented, insensitive compares are not part of the C standard.
With C99 implicit functions require a diagnostic (a warning in this case). Without C99, the implicit use of the function generates no warning. The functions exists in this compiler's library - it is just a question of are the functions declared before use.
Easy enough to make your own:
int wal_stricmp(const char *a, const char *b) {
int ca, cb;
do {
ca = (unsigned char) *a++;
cb = (unsigned char) *b++;
ca = tolower(toupper(ca));
cb = tolower(toupper(cb));
} while (ca == cb && ca != '\0');
return ca - cb;
}
Note: When coding and trying to make A-Z
match a-z
, string insensitive compare routines tend to work uniformly well. But when trying to to order strings, things quickly get out of hand. "abc" vs. "_bc" can come before or after the other depending on if compassion was done as upper or lower case. '_'
, in ASCII, exists between the upper and lower case letters. With internationalization and locale issues, the situation becomes more complex. My code example uses a round-trip of conversion to cope with issues where the number of uppercase char
does not have a 1-to-1 mapping with lowercase ones. IMO the complexities of robust case insensitive compares obliges the use of UTF encoding and its case definition.
[Edit 2020]
To cope with those forlorned non-2's complement as well as 2's complement platforms, a code correction is warranted. Earlier code would fold a +0 and -0 into an unsigned
0. Only the +0 should convert to 0. Proper to read the data as unsigned char
rather than signed char
and convert.
Note: the proper handle in non-2's complement is mostly academic now.
// ca = (unsigned char) *a++;
ca = *((unsigned char *) a++);
// also cb
stricmp
and strincmp
are both non standard functions. They have never been a part of the C standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With