Is the function strcmpi in the C standard libary of ISO? - c

I noticed that the difference between linux and windows.
strcmpi is in windows C standard libary implementation but it is not in GNU's C standard libary implementation.
Is the function strcmpi in the C standard libary defined by ISO?
How can I get the standard file?
Thank you.

The POSIX Standard (aka, UNIX) has strcasecmp() but it's not part of C99 / ISO-C.
Note: If you compare the above reference with e.g. the one for strcmp() you'll note that the latter explicitly references ISO-C, while the former does not. An useful feature of the OpenGroup references.
Edit: Since the locale-dependency was mentioned as a complication, see the above reference for strcasecmp_l() which allows explicitly specifying the locale to be used for the conversion. Windows has _strcmpi_l() for the purpose, again keeping with its own naming conventions.

Nope, it's a non-standard extension. Unix-like systems commonly have a strcasecmp which performs the same task as MS's strcmpi.

Nope, a quick CTRL+F in the standard returns nothing for strcmpi. This means that it is a non-standard extension (of which both Windows and GNU have a lot).

Related

Why do Windows and Linux have different strdup implementations: strdup() and _strdup()?

When working with strdup on Windows I found out that _strdup is Windows specific, but when I ran the same code on Linux it required strdup without the underscore. Does anyone know the history behind this difference, as-well as some information on how you have dealt with this problem when writing cross-platform code?
There are several functions that are part of the POSIX specification, i.e. Linux and most other UNIX variants, that are not part of standard C. These include strdup, write, read, and others.
The reasoning for the leading underscore is as follows, taken from the MSDN docs:
The Universal C Run-Time Library (UCRT) supports most of the C
standard library required for C++ conformance. It implements the C99
(ISO/IEC 9899:1999) library, with certain exceptions: The type-generic
macros defined in , and strict type compatibility in
. The UCRT also implements a large subset of the POSIX.1
(ISO/IEC 9945-1:1996, the POSIX System Application Program Interface)
C library. However, it's not fully conformant to any specific POSIX
standard. The UCRT also implements several Microsoft-specific
functions and macros that aren't part of a standard.
Functions specific to the Microsoft implementation of Visual C++ are
found in the vcruntime library. Many of these functions are for
internal use and can't be called by user code. Some are documented for
use in debugging and implementation compatibility.
The C++ standard reserves names that begin with an underscore in the
global namespace to the implementation. Both the POSIX functions and
Microsoft-specific runtime library functions are in the global
namespace, but aren't part of the standard C runtime library. That's
why the preferred Microsoft implementations of these functions have a
leading underscore. For portability, the UCRT also supports the
default names, but the Microsoft C++ compiler issues a deprecation
warning when code that uses them is compiled. Only the default names
are deprecated, not the functions themselves. To suppress the warning,
define _CRT_NONSTDC_NO_WARNINGS before including any headers in code
that uses the original POSIX names.
I've handled that by having a #define that check if the program is being compiled for Windows, and if so create another #define to map the POSIX name to the Windows specific name. There are a few choices you can check, although probably the most reliable is _MSC_VER which is defined if MSVC is the compiler.
#ifdef _MSC_VER
#define strdup(p) _strdup(p)
#endif

What is the purpose of Microsoft's underscore C functions?

This question is about the same subject as strdup or _strdup? but it is not the same. That question asks how to work around MS's renamings, this question asks why they did it in the first place.
For some reason Microsoft has deprecated a whole slew of POSIX C functions and replaced them with _-prefixed variants. One example among many is isatty:
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-isatty
This POSIX function is deprecated. Use the ISO C++ conformant _isatty instead.
What exactly is ISO C++ conformant about _isatty? It appears to me that the MSDN help is totally wrong.
The other questions answer explained how to deal with this problem. You add the _CRT_NONSTDC_NO_DEPRECATE define. Fine. But I want to know what Microsoft's thinking is. What was their point in renaming and deprecating functions? Was it just to make C programmers lives even harder?
The fact that _isatty() is ISO C++ conformant makes sense if you think of it like a language-lawyer.
Under ISO C++, the compiler is only supposed to provide the functions in the standard (at least for the standard headers) -- they're not allowed to freely add extra functions, because it could conflict with functions declared in the code being compiled. Since isatty() is not listed in the standard, providing an isatty() function in a standard header would not be ISO C++ compliant.
However, the standard does allow the compiler to provide any function it wants as long as the function starts with a single underscore. So -- language lawyer time -- _isatty() is compliant with ISO C++.
I believe that's the logic that leads to the error message being phrased the way it is.
(Now, in this specific case, isatty() was provided in io.h, which is not actually a C++ standard header, so technically Microsoft could provide it and still claim to be standards-conformant. But, they had other non-compliant functions like strcmpi() in string.h, which is a standard header. So, for consistency, they deprecated all of the POSIX functions the same way and they all report the same error message.)
Names starting with an underscore, like _isatty are reserved for the implementation. They do not have a meaning defined by ISO C++, nor by ISO C, and you can't use them for your own purposes. So Microsoft is entirely right in using this prefix, and POSIX is actually wrong.
C++ has namespaces, so a hypthetical "Posix C++" could define namespace posix, but POSIX has essentially become fossilized - no new innovation in that area.
isatty & co., although POSIX, are not standard C, and are provided as "extensions" by the VC++ runtime1.
As such, they are prefixed with an underscore supposedly to avoid name clashes - as names starting with an underscore followed by a lowercase letter are reserved for implementation-defined stuff at global scope. So if, for example, you wanted to use an actual POSIX compatibility layer providing its own versions of these functions, they wouldn't have to fight with the VC++-provided "fake" ones for the non-underscored names.
Extensions which have no presumption to be actually POSIX-compliant, by the way.

What is included in C Standard library?

I will give an example from The GNU C Library documentation:
13.1 Opening and Closing Files
This section describes the primitives for opening and closing files
using file descriptors. The open and creat functions are declared in
the header file fcntl.h, while close is declared in unistd.h.
My question is:
Can unistd.h and fcntl.h be considered as Standard C? As far as I know, they should be part of the Posix standard?
Can we say C Standard Library = Posix functions + C API? I am confused because Wikipedia page for C Standard Library does not include unistd.h but the GNU C Library documentation includes it?
No, unistd.h, fcntl.h, etc, are not standard C.
In general, standard C doesn't include functions that deal with low level file manipulation. For example, fopen, fread, and fwrite are part of standard C library. While POSIX open, read, write functions are not standard C.
As far as I can see, in C11 standard, there is no unistd.h and fcntl.h. So, strictly speaking, they are not part of the C standard.
When it comes to the implementation part, the GNU C library (glibc) is one of them. From the wiki page
glibc provides the functionality required by the Single UNIX Specification, POSIX (1c, 1d, and 1j) and some of the functionality required by ISO C11, ISO C99, Berkeley Unix (BSD) interfaces, the System V Interface Definition (SVID) and the X/Open Portability Guide (XPG), Issue 4.2, with all extensions common to XSI (X/Open System Interface) compliant systems along with all X/Open UNIX extensions.
In addition, glibc also provides extensions that have been deemed useful or necessary while developing GNU.
So, as a part of the POSIX standard, they are available in glibc.
Reference: Check the C11 standard draft version here.

Are there any free implementations of strcpy_s and/or TR24731-1?

I have an old project that is mixed C and C++. It makes extensive use of C strings and of strcpy,strcat,strncpy,strncat etc. I've uncovered a number of buffer overflows, and I'd like to use more secure functions, such as strcpy_s. MSVC includes those functions, but I need something that will work on various platforms - linux, osx, and windows at the least.
I do know of strlcpy, but as plenty of people have noted (example), it really isn't an improvement.
So: Are there any free implementations of strcpy_s, strcat_s, etc, or of the entire TR24731-1?
I need something that's either public domain or BSD, but if you know of implementations under other licenses, go ahead and list them - I'm sure someone else will benefit.
Try with the Safe C library. It's under the MIT license and according to this list implements the functions you're looking for:
The Safe C Library provides bound checking memory and string functions per ISO/IEC TR24731.
These functions are alternative functions to the existing standard C library that promote safer, more secure programming
You can use memcpy and memset etc, which are portable and safer than string functions.
Why not using strncpy and strncat? Contrary to strlcpy and strlcat, they are standard C functions. These functions are not perfect but you can use them safely.
And also note that the bounds-checking _s functions are optional in the current Standard.

Is the term "libc" equivalent to "C standard library"?

I sometimes hear people using the terms "libc" and "C standard library" interchangeably. I understand that "libc" is the name (or part of the names) of many popular C standard library implementations. My guess is that because of the widespread use of these implementations, people started referring to the C standard library in general as "libc" although it is not an official name.
Is it correct to refer to the C standard library as "libc"?
I always thought that "libc" just happens to be the name (or part of the names) of many popular C standard library implementations.
This is correct. "libc" is the name of some implementations of the C Standard Library.
As an example of a C Standard Library implementation that is not named "libc," the Microsoft C Standard Library implementation is a part of the "C Run-Time Libraries," usually referred to as the "CRT."
Is it correct to refer to the C standard library as "libc"?
The C Standard Library is not named "libc," so using that term to refer to it generically (and not to a particular implementation) would be incorrect. That said, in most contexts, if you did use the term "libc" to refer to the C Standard Library, you are still likely to be understood.
"libc" is indeed the name of the implementation. It often includes functions that are not part of the C standard, and might not include functions that are part of the C standard. (A common case of the latter is the Standard C math functions being split into a separate "libm".)
'libc' refers to the C standard library. However, the libc has several implementations :
glibc : an implementation of libc written for the GNU Project
klibc : a minimalistic subset implementation of the libc
...
LibC (http://www.gnu.org/s/libc/) is one particular implementation of the C library standard (http://en.wikipedia.org/wiki/C_standard_library#ISO_Standard).

Resources