What is the meaning of char foo(|10|) in C? - c

I'm a very experienced C programmer, but recently I came across some code on a mainframe that has a local variable. This is in a simple C function that declares this variable, and then strcpy / strcats two strings into it, and then tries an fopen.
char foo(|10|);
This code is very old. Possibly even K&R C old. I'm wondering if this is some obscure compiler extension or an adaptation to a keyboard that doesn't have [] or something like that.
Anyone know if this declaration is 'special'?
This is a standard Z/OS mainframe. I'm not sure what compiler is used.

It seems to be an early or non-standard form of digraph. The code was probably written using EBCDIC instead of ASCII, and EBCDIC doesn't have [ ] characters (at least not in all code pages).
I found the manual for SAS/C, a C compiler apparently meant for System/370. On page 2-10 (page 42 of the pdf) you can see they list (| |) as "alternate forms" for [ ].
(Though apparently | is not in all the code pages either; but maybe it was in a code page that was more commonly used? I don't know.)
C99 also included digraphs (and trigraphs) to solve the same problem, but they used <: :> as the digraphs, and ??( ??) for the trigraphs.

Related

Does C have namespaces similar to C++?

From Programming Language Pragmatics by Michael Scott
Modern versions of C and C++ include a namespace mechanism
that provides module-like data hiding
Does C have namespaces similar to C++?
Are the "identifier name spaces" mentioned in C in a Nutshell the "namespaces" mentioned in Scott's book, and similar to namespaces in C++?
Thanks.
No, C does not have a namespace mechanism whereby you can provide “module-like data hiding”.
book quality
I do not know anything about the book you cited, but the word “namespaces” is one of those that gets overloaded to a lot of different meanings, just like “window”. (I question the validity of anything the author says for getting such a major point about one of the world’s oldest and most widespread computer languages so brazenly wrong.)
name spaces in C
“Name spaces” in C are a completely different mechanism, working for a completely different purpose. These are the name spaces discussed in “C in a Nutshell”. The words mean something different than C++ namespaces. Since David Rankin bothered to lookup chapter and section referencing the C11 Standard, these are the name spaces used in C:
label names
struct/union/enum tags
struct/union members
everything else (including enum values)
a quick blurb about scope
Keep in mind that this says nothing about scope, which is a separate mechanism. For example, a global variable and a variable local to a function may have the same name; nevertheless they share the same name space. The difference is that the global’s visibility is obscured by the local variable.
value of namespaces in C++
It is still unclear whether namespaces were a very useful extension to C++, and the argument as to its righteousness continues. The C crowd (mostly) agrees that the headache that adding namespaces would involve doesn’t justify the ends. I couldn’t find anything particularly useful on the interwebs right off the top of my keyboard, except for a couple of bland blurbs about emulating them using structs or (even worse) using macro abuse. If you really want to dig, you could probably find some useful discussions archived on the comp.lang.c newsgroup.
No, C has nothing like C++ namespaces. Most people have to fake what C++ does using a kind of underscore notation at best. This is at least what I do instead of trying to pack things into structs. Your IDE will still help with code assists, you just have to get used to using the underscore instead of a . for everything
C++
MyNamespace::MyObject.myMethodOrVar ...
Ends up looking like this in C
MyNamespace_MyObject_myMethodOrVar
May not be as smooth as C++ or Java, but it works and still helps avoid name collision. It's just a pain in the ass.
And yes, this doesn't give you syntactic devices like use. It is what it is I'm afraid.

Getting a Dev-C++ built program to output UNICODE characters to the Windows command line

If you can answer any of my questions, that would be awesome.
Here's the scoop: I'm teaching an intro to programming class in Thailand to 11th graders. It's been going great so far, their level of English is high enough that I can teach in English and have them write programs in English and everything is fine and dandy.
However, as speakers of a language with non-Latin characters, I feel that they should at least learn what UNICODE is. I won't test them on it or bog them down with implementation details, but I want to show them an example of a UNICODE program that can do I/O with Thai characters.
I'm operating under the following constraints, none of which can be changed (at least for this semester):
The program must run on Windows 7
The program must be in C (not C++)
We must use Dev-C++ (v. 4.9.9.3) as our IDE (I'm going to try and convince the admins to change for next semester, but they may not want to)
The program should output to the Command Line (I'd like it to "look like" the programs we've been writing so far)
I want it to be easy to set up and run, though I'm not opposed to including a Batch file to do some setup work for the kids.
Here's how far I've gotten, and the questions I have:
In Control Panel > Regions > Administrative > Language for non-UNICODE programs is set to Thai.
I used "chcp 874" to set the Thai codepage in the Command Line, but characters from the keyboard come appear as garbage characters. Is this maybe because the keyboard mappings are wrong or do I have to change something else?
I wrote a program with the line: printf("\u0E01\n"); which prints ก, the first letter in the Thai alphabet. Is that the right syntax?
I received a compiler warning that "Universal Characters are only supported in C++ and C99." Does Dev-C++ not compile to C99? Is there a way I could get a C99 compiler for it?
I ran the code and got garbage characters. I imagine this could be because of the compiler, the command line, or any number of other things.
I'd love to end this course with a program that outputs สวัสดีโลก, the Thai equivalent of "Hello World!" I've done tons of googling, but every answer I've found either doesn't work in this specific case or involved a different IDE.
Ok, here's my bit of help. I don't use Dev-C++ as my IDE, so I can't help you with IDE specific things, but the following is standard to most C/C++ compilers:
wprintf is the printf implementation for wide characters (unicode).
When using wide characters you will use wchar_t in place of char for defining strings.
so you might do something like this
#include <wchar.h>
int main(int argc, char** argv) {
wchar_t* str = L"สวัสดีโลก";
wprintf(L"%s", str);
system("pause");
return 0;
}
wprintf is most likely what you're looking for.
Other functions for printing and manipulating wide strings can be found by researching the wchar.h header file.
Reference:
wprintf - C++ Reference
Using L before the quotations means you intend to define a wide string. (unicode)
Hope that helps,
-Dave
I have never used DEV-C++ IDE :-) However, after reading up on it a bit I see that
dev-c++ version 4.9.9.3 uses gcc-3.5.4 mingw port. Which has universal character support status of "Done" see http://gcc.gnu.org/gcc-3.4/c99status.html for details. You have to change the IDE configuration such that the compiler uses -std=c99 as part of the compiler flags.
Hopefully that will do the trick.
I will try to fiddle with it on my own system and see how far we can get. Will update the answer if I find more clues :-)
If you need to change the code page in a console C program, you can add the header <stdlib.h> and the line system("CHCP 874"); at the beginning of the program.
If you need a free compiler conforming with C99 under windows, you can try Pelles C:
http://www.christian-heffner.de/index.php?page=download&lang=en
It is conforming at all with C99.
You have to use wide-string constants, that have the following syntax:
L"Wide string\n"
Instead of printf(), you need to use wprintf() and the like.
http://pubs.opengroup.org/onlinepubs/7908799/xsh/wchar.h.html

Why C standards contain many unsafe functions, which are useless?

Why C standards contain many unsafe functions, which are useless (in good programs them don't use) and harmful, for example getchar? Why C standard doesn't contain instead of them the useful functions, for example getch, and getche? It is only one of many examples...
UPD
I confused: gets instead of getchar.
Do you mean gets? To not break old programs. The road to obsoleteness is long.
And besides, it has been deprecated.
gets is deprecated in C99 and has been removed in C11.
C11(ISO/IEC 9899:201x) Forward/6
removed the gets function ()
You can't implement getch() [reading without buffering] on a teletype (terminal that looks like a typewriter). Or any type of terminal where the data is stored in the terminal until you hit enter.
There are functions that do this sort of things, but remember that C is a language that is supposed to "run on anything".
gets was part of the standard library many years ago, so it has to stay - otherwise, old code won't compile, and a lot of people like to use old code (because it's a lot of work to fix up 1000000 lines of messy code that used to work!)

How would I implement something similar to the Objective-C #encode() compiler directive in ANSI C?

The #encode directive returns a const char * which is a coded type descriptor of the various elements of the datatype that was passed in. Example follows:
struct test
{ int ti ;
char tc ;
} ;
printf( "%s", #encode(struct test) ) ;
// returns "{test=ic}"
I could see using sizeof() to determine primitive types - and if it was a full object, I could use the class methods to do introspection.
However, How does it determine each element of an opaque struct?
#Lothars answer might be "cynical", but it's pretty close to the mark, unfortunately. In order to implement something like #encode(), you need a full blown parser in order to extract the the type information. Well, at least for anything other than "trivial" #encode() statements (i.e., #encode(char *)). Modern compilers generally have either two or three main components:
The front end.
The intermediate end (for some compilers).
The back end.
The front end must parse all the source code and basically converts the source code text in to an internal, "machine useable" form.
The back end translates the internal, "machine useable" form in to executable code.
Compilers that have an "intermediate end" typically do so because of some need: they support multiple "front ends", possibly made up of completely different languages. Another reason is to simplify optimization: all the optimization passes work on the same intermediate representation. The gcc compiler suite is an example of a "three stage" compiler. llvm could be considered an "intermediate and back end" stage compiler: The "low level virtual machine" is the intermediate representation, and all the optimization takes place in this form. llvm also able to keep it in this intermediate representation right up until the last second- this allows for "link time optimization". The clang compiler is really a "front end" that (effectively) outputs llvm intermediate representation.
So, if you want to add #encode() functionality to an 'existing' compiler, you'd probably have to do it as a "source to source" 'compiler / preprocessor'. This was how the original Objective-C and C++ compilers were written- they parsed the input source text and converted it to "plain C" which was then fed in to the standard C compiler. There's a few ways to do this:
Roll your own
Use yacc and lex to put together a ANSI-C parser. You'll need a grammar- ANSI C grammar (Yacc) is a good start. Actually, to be clear, when I say yacc, I really mean bison and flex. And also, loosely, the other various yacc and lex like C-based tools: lemon, dparser, etc...
Use perl with Yapp or EYapp, which are pseudo-yacc clones in perl. Probably better for quickly prototyping an idea compared to C-based yacc and lex- it's perl after all: Regular expressions, associative arrays, no memory management, etc.
Build your parser with Antlr. I don't have any experience with this tool chain, but it's another "compiler compiler" tool that (seems) to be geared more towards java developers. There appears to be freely available C and Objective-C grammars available.
Hack another tool
Note: I have no personal experience using any of these tools to do anything like adding #encode(), but I suspect they would be a big help.
CIL - No personal experience with this tool, but designed for parsing C source code and then "doing stuff" with it. From what I can glean from the docs, this tool should allow you to extract the type information you'd need.
Sparse - Worth looking at, but not sure.
clang - Haven't used it for this purpose, but allegedly one of the goals was to make it "easily hackable" for just this sort of stuff. Particularly (and again, no personal experience) in doing the "heavy lifting" of all the parsing, letting you concentrate on the "interesting" part, which in this case would be extracting context and syntax sensitive type information, and then convert that in to a plain C string.
gcc Plugins - Plugins are a gcc 4.5 (which is the current alpha/beta version of the compiler) feature and "might" allow you to easily hook in to the compiler to extract the type information you'd need. No idea if the plugin architecture allows for this kind of thing.
Others
Coccinelle - Bookmarked this recently to "look at later". This "might" be able to do what you want, and "might" be able to do it with out much effort.
MetaC - Bookmarked this one recently too. No idea how useful this would be.
mygcc - "Might" do what you want. It's an interesting idea, but it's not directly applicable to what you want. From the web page: "Mygcc allows programmers to add their own checks that take into account syntax, control flow, and data flow information."
Links.
CocoaDev Objective-C Parsing - Worth looking at. Has some links to lexers and grammars.
Edit #1, the bonus links.
#Lothar makes a good point in his comment. I had actually intended to include lcc, but it looks like it got lost along the way.
lcc - The lcc C compiler. This is a C compiler that is particularly small, at least in terms of source code size. It also has a book, which I highly recommend.
tcc - The tcc C compiler. Not quite as pedagogical as lcc, but definitely still worth looking at.
poc - The poc Objective-C compiler. This is a "source to source" Objective-C compiler. It parses the Objective-C source code and emits C source code, which it then passes to gcc (well, usually gcc). Has a number of Objective-C extensions / features that aren't available in gcc. Definitely worth looking at.
You would implement this by implementing the ANSI C compiler first and then add some implementation specific pragmas and functions to it.
Yes i know this is cynical answer and i accept the downvotes.
One way to do it would be to write a preprocessor, which reads the source code for the type definitions and also replaces #encode... with the corresponding string literal.
Another approach, if your program is compiled with -g, would be to write a function that reads the type definition from the program's debug information at run-time, or use gdb or another program to read it for you and then reformat it as desired. The gdb ptype command can be used to print the definition of a particular type (or if that is insufficient there is also maint print type, which is sure to print far more information than you could possibly want).
If you are using a compiler that supports plugins (e.g. GCC 4.5), it may also be possible to write a compiler plugin for this. Your plugin could then take advantage of the type information that the compiler has already parsed. Obviously this approach would be very compiler-specific.

Do you use the TR 24731 'safe' functions? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
The ISO C committee (ISO/IEC JTC1/SC21/WG14) has published TR 24731-1 and is working on TR 24731-2:
TR 24731-1: Extensions to the C Library Part I: Bounds-checking interfaces
WG14 is working on a TR on safer C library functions. This TR is oriented towards modifying existing programs, often by adding an extra parameter with the buffer length. The latest draft is in document N1225. A rationale is in document N1173. This is to become a Technical Report type 2.
TR 24731-2: Extensions to the C Library - Part II: Dynamic allocation functions
WG14 is working on a TR on safer C library functions. This TR is oriented towards new programs using dynamic allocation instead of an extra parameter for the buffer length. The latest draft is in document N1337. This is to become a Technical Report type 2.
Questions
Do you use a library or compiler with support for the TR24731-1 functions?
If so, which compiler or library and on which platform(s)?
Did you uncover any bugs as a result of fixing your code to use these functions?
Which functions provide the most value?
Are there any that provide no value or negative value?
Are you planning to use the library in the future?
Are you tracking the TR24731-2 work at all?
I have been a vocal critic of these TRs since their inception (when it was a single TR) and would never use them in any of my software. They mask symptoms instead of addressing causes and it is my opinion that if anything they will have a negative impact on software design as they provide a false sense of security instead of promoting existing practices that can accomplish the same goals much more effectively. I am not alone, in fact I am not aware of a single major proponent outside of the committee developing these TRs.
I use glibc and as such know that I will be spared having to deal with this nonsense, as Ulrich Drepper, lead maintainer for glibc, said about the topic:
The proposed safe(r) ISO C library
fails to address to issue completely.
... Proposing to make the life of a
programmer even harder is not going to
help. But this is exactly what is
proposed. ... They all require more
work to be done or are just plain
silly.
He goes on to detail problems with a number of the proposed functions and has elsewhere indicated that glibc would never support this.
The Austin Group (responsible for maintaining POSIX) provided a very critical review of the TR, their comments and the committee responses available here. The Austin Group review does a very good job detailing many of the problems with the TR so I won't go into individual details here.
So the bottom line is: I don't use an implementation that supports or will support this, I don't plan on ever using these functions, and I see no positive value in the TR. I personally believe that the only reason the TR is still alive in any form is because it is being pushed hard by Microsoft who has recently proved very capable of getting things rammed though standards committees despite wide-spread opposition. If these functions are ever standardized I don't think they will ever become widely used as the proposal has been around for a few years now and has failed to garner any real community support.
Direct answer to question
I like Robert's answer, but I also have some views on the questions I raised.
Do you use a library or compiler with support for the TR24731-1 functions?
No, I don't.
If so, which compiler or library and on which platform(s)?
I believe the functions are provided by MS Visual Studio (MS VC++ 2008 Edition, for example), and there are warnings to encourage you to use them.
Did you uncover any bugs as a result of fixing your code to use these functions?
Not yet. And I don't expect to uncover many in my code. Some of the other code I work with - maybe. But I've yet to be convinced.
Which functions provide the most value?
I like the fact that the printf_s() family of functions do not accept the '%n' format specifier.
Are there any that provide no value or negative value?
The tmpfile_s() and tmpnam_s() functions are a horrible disappointment. They really needed to work more like mkstemp() which both creates the file and opens it to ensure there is no TOCTOU (time-of-check, time-of-use) vulnerability. As it stands, those two provide very little value.
I also think that strerrorlen_s() provides very little value.
Are you planning to use the library in the future?
I am in two minds about it. I started work on a library that would implement the capabilities of TR 24731 over a standard C library, but got caught by the amount of unit testing needed to demonstrate that it is working correctly. I'm not sure whether to continue that. I have some code that I want to port to Windows (mainly out of a perverse desire to provide support on all platforms - it's been working on Unix derivatives for a couple of decades now). Unfortunately, to get it to compile without warnings from the MSVC compilers, I have to plaster the code with stuff to prevent MSVC wittering about me using the perfectly reliable (when carefully used) standard C library functions. And that is not appetizing. It is bad enough that I have to deal with most of two decades worth of a system that has developed over that period; having to deal with someone's idea of fun (making people adopt TR 24731 when they don't need to) is annoying. That was partly why I started the library development - to allow me to use the same interfaces on Unix and Windows. But I'm not sure what I'll do from here.
Are you tracking the TR24731-2 work at all?
I'd not been tracking it until I went to the standards site while collecting the data for the question. The asprintf() and vasprintf() functions are probably valuable; I'd use those. I'm not certain about the memory stream I/O functions. Having strdup() standardized at the C level would be a huge step forward. This seems less controversial to me than the part 1 (bounds checking) interfaces.
Overall, I'm not convinced by part 1 'Bounds-Checking Interfaces'. The material in the draft of part 2 'Dynamic Allocation Functions' is better.
If it were up to me, I'd move somewhat along the lines of part 1, but I'd also revised the interfaces in the C99 standard C library that return a char * to the start of the string (e.g. strcpy() and strcat()) so that instead of returning a pointer to the start, they'd return a pointer to the null byte at the end of the new string. This would make some common idioms (such as repeatedly concatenating strings onto the end of another) more efficient because it would make it trivial to avoid the quadratic behaviour exhibited by code that repeatedly uses strcat(). The replacements would all ensure null-termination of output strings, like the TR24731 versions do. I'm not wholly averse to the idea of the checking interface, nor to the exception handling functions. It's a tricky business.
Microsoft's implementation is not the same as the standard specification
Update (2011-05-08)
See also this question. Sadly, and fatally to the usefulness of the TR24731 functions, the definitions of some of the functions differs between the Microsoft implementation and the standard, rendering them useless (to me). My answer there cites vsnprintf_s().
For example, TR 24731-1 says the interface to vsnprintf_s() is:
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdarg.h>
#include <stdio.h>
int vsnprintf_s(char * restrict s, rsize_t n,
const char * restrict format, va_list arg);
Unfortunately, MSDN says the interface to vsnprintf_s() is:
int vsnprintf_s(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format,
va_list argptr
);
Parameters
buffer - Storage location for output.
sizeOfBuffer - The size of the buffer for output.
count - Maximum number of characters to write (not including the terminating null), or _TRUNCATE.
format - Format specification.
argptr - Pointer to list of arguments.
Note that this is not simply a matter of type mapping: the number of fixed arguments is different, and therefore irreconcilable. It is also unclear to me (and presumably to the standards committee too) what benefit there is to having both 'sizeOfBuffer' and 'count'; it looks like the same information twice (or, at least, code will commonly be written with the same value for both parameters).
Similarly, there are also problems with scanf_s() and its relatives. Microsoft says that the type of the buffer length parameter is unsigned (explicitly stating 'The size parameter is of type unsigned, not size_t'). In contrast, in Annex K, the size parameter is of type rsize_t, which is the restricted variant of size_t (rsize_t is another name for size_t, but RSIZE_MAX is smaller than SIZE_MAX). So, again, the code calling scanf_s() would have to be written differently for Microsoft C and Standard C.
Originally, I was planning to use the 'safe' functions as a way of getting some code to compile cleanly on Windows as well as Unix, without needing to write conditional code. Since this is defeated because the Microsoft and ISO functions are not always the same, it is pretty much time to give up.
Changes in Microsoft's vsnprintf() in Visual Studio 2015
In the Visual Studio 2015 documentation for vsnprintf(), it notes that the interface has changed:
Beginning with the UCRT in Visual Studio 2015 and Windows 10, vsnprintf is no longer identical to _vsnprintf. The vsnprintf function complies with the C99 standard; _vnsprintf is retained for backward compatibility.
However, the Microsoft interface for vsnprintf_s() has not changed.
Other examples of differences between Microsoft and Annex K
The C11 standard variant of localtime_s() is defined in ISO/IEC 9899:2011 Annex K.3.8.2.4 as:
struct tm *localtime_s(const time_t * restrict timer,
struct tm * restrict result);
compared with the MSDN variant of localtime_s() defined as:
errno_t localtime_s(struct tm* _tm, const time_t *time);
and the POSIX variant localtime_r() defined as:
struct tm *localtime_r(const time_t *restrict timer,
struct tm *restrict result);
The C11 standard and POSIX functions are equivalent apart from name. The Microsoft function is different in interface even though it shares a name with the C11 standard.
Another example of differences is Microsoft's strtok_s() and Annex K's strtok_s():
char *strtok_s(char *strToken, const char *strDelimit, char **context);
vs:
char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr);
Note that the Microsoft variant has 3 arguments whereas the Annex K variant has 4. This means that the argument list to Microsoft's strtok_s() is compatible with POSIX's strtok_r() — so calls to these are effectively interchangeable if you change the function name (e.g. by a macro) — but the Standard C (Annex K) version is different from both with the extra argument.
The question Different declarations of qsort_r() on Mac and Linux has an answer that also discusses qsort_s() as defined by Microsoft and qsort_s() as defined by TR24731-1 — again, the interfaces are different.
ISO/IEC 9899:2011 — C11 Standard
The C11 standard (December 2010 Draft; you could at one time obtain a PDF copy of the definitive standard, ISO/IEC 9899:2011, from the ANSI web store for 30 USD) does have the TR24731-1 functions in it as an optional part of the standard. They are defined in Annex K (Bounds-checking Interfaces), which is 'normative' rather than 'informational', but it is optional.
The C11 standard does not have the TR24731-2 functions in it — which is sad because the vasprintf() function and its relatives could be really useful.
Quick summary:
C11 contains TR24731-1
C11 does not contain TR24731-2
C18 is the same as C11 w.r.t TR24731.
Proposal to remove Annex K from the successor to C11
Deduplicator pointed out in a comment to another question that there is a proposal before the ISO C standard committee (ISO/IEC JTC1/SC22/WG14)
N1967 Field Experience with Annex K — Bounds Checking Interfaces
It contains references to some of the extant implementations of the Annex K functions — none of them widely used (but you can find them via the document if you are interested).
The document ends with the recommendation:
Therefore, we propose that Annex K be either removed from the next revision of the C standard, or deprecated and then removed.
I support that recommendation.
The C18 standard did not alter the status of Annex K. There is a paper N2336 advocating for making some changes to Annex K, repairing its defects rather than removing it altogether.
Ok, now a stand for TR24731-2:
Yes, I've used asprintf()/vasprintf() ever since I've seen them in glibc, and yes I am a very strong advocate of them.
Why?
Because they deliver precisely what I need over and over again: A powerful, flexible, safe and (relatively) easy to use way to format any text into a freshly allocated string.
I am also much in favor of the memstream functions: Like asprintf(), open_memstream() (not fmemopen()!!!) allocates a sufficiently large buffer for you and gives you a FILE* to do your printing, so your printing functions can be entirely ignorant of whether they are printing into a string or a file, and you can simply forget about how much space you will need.
Do you use a library or compiler with support for the TR24731-1 functions?
If so, which compiler or library and on which platform(s)?
Yes, Visual Studio 2005 & 2008 (for Win32 development obviously).
Did you uncover any bugs as a result of fixing your code to use these functions?
Sort of.... I wrote my own library of safe functions (only about 15 that we use frequently) that would be used on multiple platforms -- Linux, Windows, VxWorks, INtime, RTX, and uItron. The reason for creating the safe functions were:
We had encountered a large number of bugs due to improper use of the standard C functions.
I was not satisfied with the information passed into or returned from the TR functions, or in some cases, their POSIX alternatives.
Once the functions were written, more bugs were discovered. So yes, there was value in using the functions.
Which functions provide the most value?
Safer versions of vsnprintf, strncpy, strncat.
Are there any that provide no value or negative value?
fopen_s and similar functions add very little value for me personally. I'm OK if fopen returns NULL. You should always check the return value of the function. If someone ignores the return value of fopen, what is going to make them check the return value of fopen_s? I understand that fopen_s will return more specific error information which can be useful in some contexts. But for what I'm working on, this doesn't matter.
Are you planning to use the library in the future?
We are using it now -- inside our own "safe" library.
Are you tracking the TR24731-2 work at all?
No.
No, these functions are absolutely useless and serve no purpose other than to encourage code to be written so it only compiles on Windows.
snprintf is perfectly safe (when implemented correctly) so snprintf_s is pointless. strcat_s will destroy data if the buffer is overflowed (by clearing the concatenated-to string). There are many many other examples of complete ignorance of how things work.
The real useful functions are the BSD strlcpy and strlcat. But both Microsoft and Drepper have rejected these for their own selfish reasons, to the annoyance of C programmers everywhere.

Resources