PREfast Warning 400 (Windows CE 5.0)
400 - Using <function> to perform a case-insensitive compare to constant <string>.
This warning indicates that a case-insensitive comparison to a constant string is being performed in a locale-dependent way, when it appears that a locale-independent comparison was intended.
This warning is produced on calls to functions such as
lstrcmpi
lstrcmpiA
lstrcmpiW
**Note **This warning is not produced if the constant string is the empty string (_T("")) or consists only of digits or punctuation. Even though the behavior is correct in these cases, it is probably more efficient to use a case-sensitive comparison function.
String comparisons are performed in two different situations:
Locale-dependent
In this situation, the comparison should match the user's language preferences.
For example, the user wants a list of contact names in the default order for a specific language.
In this case, a locale-dependent comparison, such as performed by lstrcmpi, or CompareString with the current locale, is appropriate.
Locale-independent
In this situation, the comparison should return the same result regardless of the user's language.
For example, the comparison determines if the extension of a file is .gif. In this case, a locale-independent comparison is appropriate.
Performing a locale-dependent comparison when a locale-independent comparison was intended can cause incorrect behavior for non-English locales. For example, in Turkish, .gif does not match .GIF; in Vietnamese, LogIn does not match LOGIN.
Usually, case-insensitive comparisons against a constant string should be performed in a locale-independent comparison. Further, names in the file system require additional considerations.
String comparisons should generally be performed with the CompareString function.
The CompareString function takes a locale as an argument; however, passing in a default locale such as the constant LOCALE_USER_DEFAULT, or the value returned from a function such as GetThreadLocale, gives different behaviors in different locales depending on the user's default.
To perform a locale-independent comparison using CompareString on Windows XP, the first parameter should be the constant LOCALE_INVARIANT.
The next code example shows how to perform a locale-independent test for whether pString matches MyGraphic.gif that ignores differences between uppercase or lowercase that also supports other operating systems.
CompareString(LOCALE_INVARIANT,
NORM_IGNORECASE,
pString,
-1,
TEXT("MyGraphic.gif"),
-1) == 2
If code must support down-level operating systems as well, the preferred way of performing a locale-independent test is this:
CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH,
SUBLANG_ENGLISH_US),
SORT_DEFAULT),
...
PREfast considers the locale to be the default locale if it arises from any of the following constructs:
Constants
LOCALE_NEUTRAL
This constant indicates a legacy issue and gives the current user's locale instead of a language-neutral locale.
LOCALE_USER_DEFAULT
LOCALE_SYSTEM_DEFAULT
LANG_USER_DEFAULT
LANG_SYSTEM_DEFAULT
Functions
- GetThreadLocale
- GetUserDefaultLCID
- GetUserDefaultLangID
- GetUserDefaultUILanguage
- GetSystemDefaultLCID
- GetSystemDefaultLangID
- GetSystemDefaultUILanguage
Example
Defective Source
return (lstrcmpi(extension,
TEXT("gif")) == 0);
Corrected Source
return (CompareString(LOCALE_INVARIANT,
NORM_IGNORECASE,
extension,
-1,
TEXT ("gif"),
-1) == 2);
Send Feedback on this topic to the authors