//C11, safe version of strcat
errno_t strcat_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2);
strcat_s() copies no more than s1max bytes to s1. The second function, strcpy_s() requires that s1max isn't bigger than the size of s2 in order to prevent an out-of-bounds read: //C11, safe version of strcpy
errno_t strcpy_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2);
Originally, all of the bounds-checking libraries were developed by Microsoft's Visual C++ team. The C11 implementation is similar but not identical.There are so many problems with this. Yet another slightly different string manipulation function? Why not standardize on one of the already existing ones, such as strlcat/strlcpy? I can see people making some big mistakes with strcat_s, since the size passed is the number of unused characters left in s1, not the size of s1. And strcpy_s can cause a segfault if given an s1max that is greater than the size of s2. Why not only copy up to the first null character?
Also, these functions have the same name as the VC++ functions, but behave differently. In VC++, strcat_s takes the size of s1, not the space remaining. People are going to google for strcat_s, read the MSDN docs, and unknowingly add buffer overflows to their code.
Finally, these functions have annoying behavior. If they hit the limits passed to them, they erase s1. No best-effort. No copy whatever fits. Just destroy the data in the destination string.
strlcat/strlcpy solve all of the problems I've mentioned. See http://www.courtesan.com/todd/papers/strlcpy.html for more info about them. It's sad to see them only supported by *BSD and OS X.
There are valid reasons not to use strlcpy, but we need something like it. What we do not need is this _s shit, which has all the same problems (which sometimes matter, and sometimes don't) WHILE BEING MASSIVELY HARDER TO USE. And what's the advantage? Just that it returns an errno. That's fine, but what about the rest of it? Just read the instructions for it - it's crap! (I can imagine why they think they want it to work this way, because it gives you a fighting chance again non-0-terminated source strings, but it's just never going to work properly if you've only got one size argument.)
Using strlcpy, by contrast, is simplicity itself.
About 99% of the time when you're using strlcpy (and strlcat), you can just do your calls, passing the same size value into each one (how convenient), then check the length of the result using strlen. Is it one less than the size of the buffer? Yes? Then assume there's an overflow, and disregard the result, assuming you even care about that. This is very straightforward to do, and (unlike this _s junk) doesn't require you to go updating counts or checking maximum values or any of that error-prone nonsense. Just one check at the end, rather than a bunch of updates and stuff scattered all through your string code.
strlcpy! Just say yes!
strlcpy's behavior is the same as snprintf: return what the length would have been if there was enough room. That way one can recover from the error and realloc enough space. C programmers are used to this pattern.
At least now we have an ironclad reason not to ever use this garbage.
[edit: I almost wonder if someone on the committee deliberately put this in to sabotage the whole "safe C string functions" farce. Reminds me of a Simpsons episode:
Speaker: Then it is unanimous, we are going to approve the bill to evacuate the town of Springfield in the great state of—
Congressman: Wait a second, I want to tack on a rider to that bill – $30 million of taxpayer money to support the perverted arts.
Speaker: All in favor of the amended Springfield-slash-pervert bill? [entire Congress boos] Bill defeated. [gavel]
As a professional C programmer, I really couldn't care less whether or not Microsoft decides to implement C11 or remain in the dark ages. That ship sailed years ago.
You can even use Clang on Windows if you need (MinGW, Cygwin or compiled with Visual Studio). I'm not sure if you can integrate Clang in VS for example, or if it is possible to access the OS C libraries from Clang.
https://github.com/rbultje/c99-to-c89
(see http://blogs.gnome.org/rbultje/2012/09/27/microsoft-visual-s...)
But if you write C11 that uses VLAs, it seems like it's still standard C11, sort of: VLAs aren't merely a vendor-specific extension, like the GCC extensions are, but an optional C11 feature which hasn't been deprecated. Nonetheless, a conforming C11 compiler doesn't have to accept your code, so in that sense your code isn't really "standard C11". Will there be more fine-grained names for the different subsets of the standard features, so you can say that such code is compliant with "maxi-C11" but not with "core C11" or something?
Can you give us a practical example of some code where variable-length arrays prove really useful?
1. Multidimensional arrays where the sizes are quasi-fixed but not known at compile time. Comes up in various kinds of grid-simulation code, for example. You could malloc() in this case, but then you lose the notational convenience of 2d arrays.
2. Refactoring code that uses #define'd constants, to take runtime instead of compile-time parameters. For example, a common first-pass to said grid-simulation code is to have some WIDTH and HEIGHT magic numbers, which you might later regret and want to make into command-line parameters. Refactoring is trivial if you have VLAs.
It also seems cleaner (to me) semantically. I can see why, implementation-wise, classic C auto arrays required constant sizes. But from a slightly higher-level perspective, whether a variable is auto or not, and whether its size is a compile-time constant or not, feel like independent decisions. It feels particularly messy that you have different notation for arrays whose sizes are known at compile time; the syntactic sugar there has some rough edges. I also find it cleaner if explicit malloc()s are used only when something beyond boilerplate is going on, letting the compiler handle the boilerplate case of allocating/deallocating a conceptually block-scoped array of size N.
void func(int M, int N, int P, double *a_flat) {
double (*a)[N][P] = (double (*)[N][P])a_flat;
// use a[i+1][j+2][k-1] instead of a_flat[((i+1)*N+(j+2))*P+k-1].If you're absolutely sure that you can handle the power, you can always call alloca and get some stack-allocated space, even with ancient C compilers. Just make sure to enforce a reasonable upper limit. Also, never mix C99-style arrays and alloca.
[1] http://www.hpl.hp.com/techreports/2004/HPL-2004-209.html [2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
It's a minor fix, but it's vastly better than what was there previously, and it's exactly the sort of change that works really well in C; incremental fixes that are carefully thought out and easy for both implementors and users to adopt.
What higher level? POSIX? Personally, I believe things like atomicity and alignment do belong into the language specification.
Also keep in mind that the multithreading support as specified by C11 is closely aligned with C++11.
C++ has always had the feeling of a language that isn't quite finished, so there's a lot of interest in where it's going next. C has the feeling of a language that does exactly what it sets out to do, so it's not really going anywhere.
There has not been much about C11.
However, the problem is that because MS doesn't adopt it, a lot of companies and projects still have coding standards that forbid the use of C99 constructs. This because of the (percieved) need to compile for Windows with MSVC some day. So MS not adopting C99 is a problem for adoption, even though most compilers support it fine.
"Originally, all of the bounds-checking libraries were developed by Microsoft's Visual C++ team. The C11 implementation is similar but not identical."
Picking a nit, but shouldn't this say "The C11 standard ..."? If C99 implementations are hard to find, I'd think it would be more so for C11.
Are there any C11 implementations? Or do you just pick the implementation and libraries that implements that largest set of C11 that are important to you?
If the guys from plan9 just get the Ken Thompson C compiler from plan9 and changed that C just a little bit, taking care that a plain C header could be added to that code the same way we could do with C++
only then, it would be possible to "just use Go" (plan9 C can be used with gcc using "fplan9-extensions")