A New C Standard Is On the Way
Esther Schindler writes "Last year, Danny Kalev — a former member of the C++ standards committed — explained the new features in C++. Now, in C11: A New C Standard Aiming at Safer Programming, he shares an overview of the changes in C — 13 years after the ratification of the C99 standard. Kalev describes the goodies in C11, including multi-threading support, safer standard libraries, and better compliance with other industry standards."
No wonder they're not popular. C99? C11? It should be "C... X!" :p
It's not on the way, it was released last year. Both gcc and clang are already a good way along implementing it, and we've added a big chunk of the library support to FreeBSD libc already.
I am TheRaven on Soylent News
That's great! I'm still using C4, and every time I compile my code blows up!
C11 will make var arrays, one of the most widely used C99 features, optional due to pressure from Microsoft, who refuses to implement C99.
No, it's finally P.
C99 -> C11, come on guys ...
Blame Microsoft, not the standards committee.
GCC had it ahead of time.
The multi-threaded stuff sounds nice. But bounds checking, really? How difficult is it to check buffer size before copying?
If I wanted plastic scissors I'd use Java. Give me my scalpel back.
Why didn't they include some simple OOP features aswell? I understand this is a language for low level programming, and needs to be close to the metal, but many OOP features don't carry any significant overhead, and could just be avoided anyway.
C runs on way too many devices without floating point support to add those as standard libraries. It wouldn't be useful on many platforms.
And C isn't about adding every feature in the world. The language itself is pretty much done. They're just changing libraries. They'll never add a major feature like closures, nor should they. If you want them, use another language when they're designed in well, not hacked on.
I still have more fans than freaks. WTF is wrong with you people?
Visual Studio added stdint.h not to comply with C, but to comply with the pending new C++ standard. Microsoft has publicly declared that they have no intention of supporting anything past C95 (basically ANSI C circa 1989 with a few tweaks).
So some of the coolest things in C99 and C11, like named initializers, compound literals, etc, will never be in Visual Studio, because C++ has refused to adopt those features from C.
The multi-threaded stuff sounds nice. But bounds checking, really? How difficult is it to check buffer size before copying?
Given the number of buffer overflow bugs that are found in C programs, apparently it's fairly difficult to do it consistently and correctly.
I've never been a fan of putting multi-threading/multi-tasking in a programming language. You get one abstraction of threads/tasks, and that's it. If you want to do it differently, you have to do it yourself with library calls. So why not leave it that way and keep the language simple?
Unless there is an awfully good reason not to (and I haven't encountered one yet), I use pthreads.
...laura
Visual Studio is explicitly a C++ implementation, and does not focus on C support. It has what effectively amounts to C89 support, but that's a legacy thing. Any support for C99 and C11 features is purely accidental, and usually happens when some header is required by both C99/C11 and C++11 (hence why it's just headers and never language features).
In the meantime, other implementations, which actually care about C as well and C++ - like gcc or clang - add C11 support fairly quick.
cause this language goes to 11
*puts on sunglasses*
I feel your pain on this, but MS has said time and again that they don't bother with the C standard because they make a C++ compiler, not a C compiler. So they only bother complying with C++98/03 and C++11. Any C99 compliance we get is essentially just due to the shared standards that C99 has with C++11. This isn't to say I excuse this decision, just a little insight as to why it took so long to get stdint.h.
C runs on way too many devices without floating point support to add those as standard libraries. It wouldn't be useful on many platforms.
Well, it already has all common math operations on floating point numbers as part of the standard language/library. Quite obviously, any vector operation can be implemented as a simple loop over the elements invoking the corresponding (already standard) scalar operation. Making them better optimized would then be a quality of implementation issue. Making this standard would mean that people could write portable code that works faster on compilers with special support for it, but still works correctly (and no slower than corresponding code with explicit loops) everywhere else.
It doesn't even require any new language features, just libraries. Just add float4 etc as structs, and define standard library functions for all operations including arithmetic. Let compilers implement them as intrinsics where that makes sense.
Maybe it doesn't make sense as part of the core standard, but it would make for a good TR.
Are you suggesting it is possible to create a program that doesn't involve buffers?
Even the simplest Hello World program uses buffers. Even fancy languages that have run-times and virtual machines use buffers. Buffers are an integral part of designing software because they are an integral part of how the machine works at the hardware level.
"I blame the programmers not the language."
Good! Now you have to change the language once or blame the programmers forever (since you shouldn't expect to change them anytime soon).
Where did C99 go awry? Some of its mandatory features proved difficult to implement in some platforms. Other C99 features were considered questionable or experimental, to such an extent that certain vendors even advised C programmers to replace C with C++.
Speak for yourself Microsoft. It is not our fault that you can't implement C99 features properly or on time. For the rest of us C99 is alive, well and popular. Just avoid Microsoft's shoddy compiler and you will be fine. Both GCC and LLVM do the job properly.
By the way, similar comments apply to Microsoft's tardy and dodgy implementation of C++11.
When all you have is a hammer, every problem starts to look like a thumb.
Quite obviously, any vector operation can be implemented as a simple loop over the elements invoking the corresponding (already standard) scalar operation. Making them better optimized would then be a quality of implementation issue. Making this standard would mean that people could write portable code that works faster on compilers with special support for it, but still works correctly (and no slower than corresponding code with explicit loops) everywhere else.
I believe the idea was that restrict pointers would help the compiler discover where it can transform existing code to use vectors.
Restrict is to help the compiler discover when it can assume the lack of aliasing, and therefore aggressively prefetch and cache values. This is especially so when combined with static size array arguments (as in int[static 4]), which by definition cannot be null, permitting compiler to fetch without any checks. I guess it can also be used to improve parallelization by letting the compiler assume lack of dependencies between reads and writes where otherwise it would have to assume they exist, but that's not quite the same as vectorization.
I know some compilers can do auto-vectorization on loops over arrays - notably Intel - but this is still too limited to be portable. Most implementations require you to use the (implementation-defined) intrinsics to do the same, which to me strongly indicates that this is the way this should be standardized. Also, writing such loops explicitly every time is unnecessarily verbose.
I'm not sure how you think printf"(hello world\n"); uses any dynamic (i.e. user-created/maintained )memory but never mind thats not my point here.
What I am saying is that you write your code such that once you created a buffer, your program knows its length and is written in such a way that it isn't possible to crash it.
For example, only use bounded functions like strncpy() rather than unbounded ones like strcpy().
What features do you want?
Automatic memory management? Isn't this what makes C++ so fucking insanely complex? Bad idea.
Overloading? Umm, that's extremely dangerous in subtle complex code like operating system schedulers, computational code, etc. Very bad idea.
Inheritance? Nah. Almost as bad as overloading, but also useless for most most activities.
Templates? No, they're even worse than overloading. I suppose Java interfaces or Haskell typeclass could provide a safe form of overloading. I certainly acknowledge the desire to parameterize a struct on another type, but that's extremely complex for a low level language.
Lambda expressions, ala C++0x? Interesting proposal, not exactly sure how the memory management works out, but perhaps one could grant the compiler the ability to build closures in this way, but subject to the programer's memory management.
Yes, I'll grant that lambda expressions make sense, but not C++0x's lambda expressions, since they impose a memory management scheme. In essence, lambda expressions in C should be just-in-time optimizations that the programer controls manually.
In truth, most object oriented language 'features' are actually bad design choices, well unless your doing GUI work where the error object oriented programming creates aren't catastrophic.
Yes, there are vaguely functional features like parametric polymorphism and lambda expressions that might aid low-level programming, but they're complex enough to require a proof-of-concept language first. C must avoid the mad dash into standardization that created C++'s complexity.
The Christian religion has been and still is the principal enemy of moral progress in the world. -- Bertrand Russell
I suppose you're not into OpenCL, right?
no -- C was based on B, which was based on BCPL. So first came BCPL, then B, then C, therefore the next one will be P.
Oddly enough all the _s crap seems to be driven by Microsoft. They proposed them, then modified their compiler to complain if you did not use them and instead used strcpy, etc. This includes functions such as snprintf which are *identical* to the _s versions, and a "safe" version of fopen that only checks if the FILE* argument is non-null (WtF?). For some reason no WIN32 api that could overflow buffers got a "_s" version and there was no warning for using them! The purpose appeared to be to piss off programmers and perhaps to discourage writing of portable software (though the warning was easily turned off).
As you point out, there have been a million replacements for gets. The original K&R book had getline() which took the buffer length and was safe. All of them had more intelligent names and more useful behavior on overflow than gets_s.
For strings there has been strlcpy and strlcat for years. Though the refusal to adopt these show the Glib maintainers have equaled Microsoft in their ability to be asses.
Anything but the pure C as defined in the sacred Whitebook pollutes the simple beauty of C and obscures the language's clarity and its similarity to the instruction sets of most common CPUs.
9/11 Eyewitnesses to Explosive WTC Demolition 1 of 2
Microsoft has publicly declared that they have no intention of supporting anything past C95
I gave up on Microsoft back when Byte magazine was in, or recently beyond, single-digit issue numbers.
A letter to the editor complained about Microsoft's support of their FORTRAN compiler: There was a bug in the floating point format handling that a customer needed to use. After several iterations of bug reports and fix requests, Microsoft had told the guy that not only had they not fixed it yet, but they were never going to fix it. IMHO that meant Microsoft had an institutional issue with customer support and adherence to standards.
Avoiding Microsoft software and products has saved me immeasurable grief over the several decades since.
Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
No, it's finally P.
Is that the same as NP?
alias sudo="echo make it yourself #" ; # https://pipedot.org/~stderr & http://soylentnews.org/~stderr
Of course, the "safer" C library string functions are already supported by Visual Studio because they're part of Microsoft's cargo-cult approach to security. You know, the one where they're so busy making everyone rewrite all their existing code to new APIs that they don't think about little details like whether it's a good idea to hand out Microsoft certificates which have code-signing permissions for no real reason and can be used to sign fake Windows updates to anyone and everyone. And where they don't bother to upgrade the signing process for those certificates to something better than MD5.
Yes, I totally think we should rewrite the linux kernel in C++
I don't know if you're trolling, but I agree, it is the logical thing to do.
Linux has many, many C++ features implemented in an ad-hoc and poorly specified way in C.
It is very heavy on OO style with derived classes and virtual functions.
TRhe C style objects are complex and require init and cleanup functions to be called.
They have imlemented type-generic macros in order to reduce code duplication effectively.
Basically, C++ takes those three things and integrates them into the language in a standard way so that everyone uses them in the same way, you get sane error messages and compiler support. C++ has one additionmal advantage that it has one global vtable per class, so each instance has a single pointer to the vtable. Linux's C-style OO has each instance having a pointer to every virtual method otherwise the syntax would be too unpleasant. This makes it less memory efficient in C and increaces the cache footprint.
The only thing worse about C++ would be that the compile times would be increased.
But that's a tiny price to pay for fewer bugs and faster code.
SJW n. One who posts facts.
gcc is pretty good at vectorisation, provided it can prove a lack of aliasing (which is very, very hard).
If you make heavy use of statically sized C-style arrays allocated on the stack, proving a lack of aliasing is much easier, and gcc generates vectorised code pretty well.
What gcc can't do is specially tag pointers allocated from malloc() as somehow similar to stack allocated arrays and assume that they don't alias in the same way. I think thbe intel compiler is much better at that, which is where many of the gains come from.
GCC is getting better however. In some cases it can prove that malloc()/free() pairs haven't achieved anything and elides them entirely. However the functionality seems pretty new and incomplete and ti doesn't work with new/delete yet.
SJW n. One who posts facts.
I blame the programmers not the language.
I blame the program architects. C isn't the right choice if you want strong typing, bounds checking, auto-alignment, the concept of finite arrays and all the other safety nets.
C is the right task for some jobs precisely because it doesn't have these features. And the wrong task for many jobs for the same reason.
Adding features like this reduces C, by making it more like other languages that already are better suited for the job.
Use C if you can handle all (and I mean all) checking yourself, be it through specs or by adding checks. Otherwise, choose a different language, don't try to transform C into something you want.
Unfortunately, this fight seems to already have been lost - some of it with C99, and more with C11. So what's a good alternative low level cross-platform language that gives you as much rope as you could possibly want?
At its core, C is designed to be a sort of portable assembly language.
No, it was designed as a replacement for assembly language. There's a difference.
Most of its original features were intended to map directly to PDP-11 opcodes
This is a myth. Most of C's original features are inherited or evolved from its predecessor languages.
http://cm.bell-labs.com/who/dmr/chist.html
Unfortunately, it hasn't really kept up with the improvements in modern instruction sets.
C has never had any direct support for the instructions of any particular machine architecture. In this, of course, it is in good company with virtually every other non assembly language because, not being assembler, you wouldn't expect it to have direct support for any particular machine instruction.
There really ought to be SIMD data types and functions built in to the language
How would you do that in a portable way?
All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
>> Some how you went from "buffer" to "dynamically allocated memory"
Yes because if you need a buffer of a length only known at runtime you should be using dynamic memory rather than statically define an array of some guessed length.
>> 1) your string isn't actually a string because it isn't null-terminated.
This is only true if you were stupid enough to make your buffer too small, which usually happens because junior or hacky programmers are often inexperienced or hacky enough to incorrectly think guessing a maximum length rather than calculating it is robust.
>> 2) it is actually more work for you to implement the handling of the error,
As opposed to what? allowing it to (possibly silently) corrupt memory?
>> I can't think of too many situations where not having the whole string is useful.
Nor can I thats why you dynamically create a buffer of suitable length.
>> By explicitly checking buffer size, I can adjust my destination buffer to include enough space
Ahh so now we are using dynamic memory?
>> if it is such a hideous problem I can simply exit() or return
Wow that must look great to the user. I hope you never write control or embedded software.
>> At which point why even bother using strncpy() if I'm already checking buffer size manually?
Both because its safer and can make your code more concise, and because the idea is that if you have a small buffer you should only read as much as you can buffer. The C and C++ language gives you exactly what you asked for. It does not generally coddle ignorant programmers by trying to second-guess everything. I personally love that, as I want a scalpel not plastic scissors.
Why do people keep modding up this old, tired tripe.
Just about everything in the article is either correct and very out of date (amazingly, the world of C++ has changed in the last 20 years) or was never true in the first place.
SJW n. One who posts facts.
Because it costs extra cycles, and you can't make the assumption that it's neglegable every single time? Because of C's promise that you don't pay for what you don't use? Because it's a logic error to begin with and you should fix your logic errors, program your intent, and not rely on the compiler to figure out what you meant? Because you want to control the binary output?
Take your pick.
"Linux's C-style OO has each instance having a pointer to every virtual method otherwise the syntax would be too unpleasant. This makes it less memory efficient in C and increaces the cache footprint."
Err, C++ vtables require a double pointer dereference - the C version requires 1. That alone is a good enough reason not to use C++. Aside from that when you;re writing an OS you want to know exactly how your memory is set up and used, not hope the compiler doesn't fuck something up when it tries to get clever.
Stick to application programming and leave kernel dev to people who know what they're doing.