strcmpi renamed to _strcmpi?
Asked Answered
S

5

9

In MSVC++, there's a function strcmpi for case-insensitive C-string comparisons.

When you try and use it, it goes,

This POSIX function is deprecated beginning in Visual C++ 2005. Use the ISO C++ conformant _stricmp instead.

What I don't see is why does ISO not want MSVC++ to use strcmpi, and why is _stricmp the preferred way, and why would they bother to rename the function, and how is a function beginning with an underscore ISO conformant. I know there must be a reason for all this, and I'm suspecting its because strcmpi is non-standard, and perhaps ISO wants non-standard extensions to begin with an _underscore?

Succumb answered 27/12, 2009 at 0:59 Comment(0)
M
13

ISO C reserves certain identifiers for future expansion (see here), including anything that starts with "str".

Meow answered 27/12, 2009 at 1:14 Comment(1)
The ISO C §7.31 Future Library Directions section §7.31.13 String handling <string.h> specifies: Function names that begin with str, mem, or wcs and a lowercase letter may be added to the declarations in the <string.h> header. This means that names such as str_lower() and strUpper() are not reserved by the C standard, but strequal() is.Jesselton
J
10

IMNSHO, this is Microsoft's way of saying "Do not put Unix software on Windows machines". There are several frustrating aspects to the problem:

  1. strcmpi() is not a POSIX function - the relevant functions are defined in <strings.h> and are called strcasecmp() etc.
  2. Even if you explicitly request support for POSIX functions, Microsoft thinks that you may not use the POSIX names but must prefix them with the wretched underscore.
  3. AFAIK, there isn't a way of overriding the MSVC compiler's view on the issue.

That said, the GCC tool chain gets a bit stroppy about some functions - mktemp() et al. However, it does compile and link successfully, despite the warnings (which are justified).

I note that MSVC also has a bee in its bonnet about snprintf() et al. If their function conformed to the C99 standard (along with the rest of the compiler), then there would never be any risk of an overflow - the standard requires null termination, contrary to the claims of Microsoft.

I haven't got a really good solution to this problem - I'm not sure there is one. One possibility is to create a header (or set of headers) to map all the actual POSIX names to Microsoft's misinterpretation of them. Another is two create a library of trivial functions with the correct POSIX name that each call down onto the Microsoft version of the name (giving you a massive collection of four-line functions - the declarator line, an open brace, a close brace, and a return statement that invokes the Microsoft variant of the POSIX function name.

It's funny how the Microsoft API calls, which also pollute the user's name space, are not deprecated or renamed.

Jesselton answered 27/12, 2009 at 2:19 Comment(2)
Well spoken! It is also annoying how MSVC insists on issuing warnings on insecure library functions and that *_s variants should be used instead.Ibo
Note that Visual Studio 2015 now has versions of vsnprintf() et al that comply with at least C99, as well as the (backwards compatible and unchanged) _vsnprintf() versions.Jesselton
A
3

Names beginning with an underscore and a lower-case letter are reserved by the C++ Standard for the C++ implementation if they are declared in the global namespace. This stops them from clashing with similar names in your own code, which must not use this naming convention.

Apostasy answered 27/12, 2009 at 1:4 Comment(0)
P
2

strcmpi goes away altogether in Visual C++ 2008, so you should definitely heed the deprecation if you ever intend to upgrade.

The _ doesn't make the function ISO standard, it's just that functions beginning with _ are safer to add as the language evolves because that's one of the parts of the namespace reserved for the language to use.

According to Microsoft's documentation for _stricmp, it sounds like strcmpi has some practices that result in some unintuitive orderings (including normalizing to lower case instead of simply treating case as irrelevant). Sounds like _stricmp takes more pains to do what one would naturally expect.

Pal answered 27/12, 2009 at 1:16 Comment(0)
R
0

My approach to retain POSIX compatibility:

// Check if on MS compiler (newer than Visual Studio 2015)
#if ( _MSC_VER > 1900 )
// redefine the name
#ifndef stricmp
#define stricmp _stricmp
#endif
#endif // _MSC_VER
Roundish answered 29/8, 2023 at 15:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.