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
Is that finally D?
That's great! I'm still using C4, and every time I compile my code blows up!
I wish new standards could be adopted more quickly. In Visual Studio it wasn't until 2010 that I could even get basic C99 headers like stdint.h.
C11 will make var arrays, one of the most widely used C99 features, optional due to pressure from Microsoft, who refuses to implement C99.
C99 -> C11, come on guys ...
The multi-threaded stuff sounds nice. But bounds checking, really? How difficult is it to check buffer size before copying?
All the fuss over C, yet there's still no "H" programming language...
Fifty watts per channel, baby cakes.
If I wanted plastic scissors I'd use Java. Give me my scalpel back.
It's time for school's to update what they teach for standard C, Even after C99 was released and C11 I had profs teaching C89, I think school's should follow suite with industry and upgrade.
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.
vector types:
I don't mean c++ vectors, I mean opencl like vectors. float4, double2, etc... and vectorized versions of the standard math libraries sin, cos, etc... So you can do true cross compiler, cross platform, and cross cpu vector programming.
closures:
In corporate Clang blocks. They are just so useful.
0... and... ...[crickets chirping]
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
multithreading support was desperately needed 15+ years ago. But now low-level multithreading model doesn't scale, and we actually need more distributed parallel processing features. Extension libraries, such as posix, can fill in support for multithreading for those rare cases where it is worthwhile. (where you need concurrency, but not a lot of concurrency)
bounds checking on the otherhand lets a programmer take advantage of information the compiler often already has available. Although I would argue that simple bound checking is too small, and would like for a full set of formal verification extensions standardized for C.
cause this language goes to 11
*puts on sunglasses*
It's not difficult at all, but people forget about doing it all the time. The point of those new interfaces is really more about forcing you to do that check (the function will do it, but you have to provide the size of the buffer to it).
Why do you need to explicitly check the buffer size at all?
A well-designed program ensures you can't crash the buffer to start with.
I blame the programmers not the language.
I don't even have to think about doing it. Often times it is as simple as an additional if statement to check the size of your source and destination buffers. If the destination buffer is smaller, just don't do the copy.
What about solving header [hell] dependency in the new C standards ?
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 he say it is possible to create a program that doesn't involve buffers? Way to deliberately misinterpret what he is saying.
What he is saying is that given the right language, buffer handling is done for you, drastically decreasing the numerous security flaws attributable to wrong buffer sizes, which is fairly common in C. Stop being obtuse in an attempt to be a pedantic troll.
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.
If it is such a problem, go use another language. One that does all the thinking for you.
"If it is such a problem, go use another language."
But he was blaming *other* programers. You don't deal with this by *you* changing to another language.
Nothing says irrelevant standard like having standardized multithreading support on year 2011.
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().
I do use a different language. Why don't you tell all those people using C to switch to a different language?
Given your responses I wonder if you really can think well enough to use C safely (and do so consistently).
If it's so simple to check the bounds size before copying, why not have the language+compiler do it by default when necessary? Because you like to type extra lines?
I'm not saying that at all. All potential buffer overflows are just a result of sloppy coding.
Even in languages with no built-in protection like C you can easily and elegantly architect your code such that crashing buffers is impossible.
People need to stop expecting languages to make up for their own lack of skill and/or attention to detail.
That's a great way to hide bugs, not fix them. If the inputs are not as expected then the result should be failure, not nothing. hence the concept of exceptions and exception handling.
I'd like an updated "The C programming language", although not necessarily by K and almost certainly not R! 'cos otherwise, I'll wind up buying some other book and I'll hate it because it's not as nice as K&R. And then I'll be all cross. :(
Some how you went from "buffer" to "dynamically allocated memory" which although related is not one and the same. I'm sure you can figure out how too look up the definitions of both and see that there is a difference.
I'll admit I misinterpreted what you wrote.
But here is the problem with strncpy() and similar functions it only reads so many characters. So if you are in a situation where more is being written into a buffer then is there;
1) your string isn't actually a string because it isn't null-terminated.
2) it is actually more work for you to implement the handling of the error, I can't think of too many situations where not having the whole string is useful. By explicitly checking buffer size, I can adjust my destination buffer to include enough space for the whole string and not loose any data OR if it is such a hideous problem I can simply exit() or return right then and there in fewer lines of code that are easier to read. At which point why even bother using strncpy() if I'm already checking buffer size manually?
Once again, only another statement, a call to exit() or return once the if statement decides your destination buffer is too small. We have a grand total of two additional statements.
Only two additional, mundane statements every time you access an array. Excellent!
Replace gets() with gets_s()! You couldn't call it something sane like get_line(), or even gets_line() to avoid name collisions. Anything connected with C++ just seems to spread its taint.
Here are two successful examples: Clang and OpenCL.
Sadly, R passed away October 12, 2011: http://en.wikipedia.org/wiki/Dennis_Ritchie
Perl Programmer for hire
Give this man some points! He has it exactly right.
Higher Logics: where programming meets science.
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
What is missing from the new standard is internationalization and localization.
Don't we already have many bloated languages out there?
The things they are adding should not be part of the language, but libraries.
The language itself should remain small, simple and elegant.
Who would think that "11" is higher than "99".
Could this be the last Y2K bug? Or is it one of those "Y2K features?"
I have a question about these different C standards.
Where am I supposed to learn how to use them?
I learned C from the K&R book mostly, however I also know that some version of C allows mixed variable declarations and various other features.
But I never really ``learned'' about these features.
So how are you supposed to learn about newer features other than some blogger saying there is some new feature.
If I go to the wikipedia page for C there is just some links to the ISO C working group and various standards.
Statements that that other languages do for you, even when you know this is not necessary making, oh tragedy, your programs to run slower.
If I sanitize my inputs on the interfacing function, all the other called functions don't have to do it again!
C is used to be used on memory/performance critical missions. Adding this bloat checking automatically will impact these missions.
Lisias@Earth.SolarSystem.OrionArm.MilkyWay.Local.Virgo.Universe.org
I'm more of a CUDA man.
OpenMP is more applicable to this discussion, but the new C11's threads.h doesn't have anything like OpenMP's "#pragma omp parallel for". If it did, then I wouldn't have brought up C11's old fashion concurrency model.
If you haven't tried OpenMP, I recommend you play it it. it will open your eyes to what can be done with a bit of C code. It's not as sophisticated as OpenCL/CUDA type solutions, but it does offer fine grain control over concurrency without bogging the programmer down in individual thread management.
Isn't that's what compiler optimisation is for - removing code that has no effect?
The multi-threaded stuff sounds nice. But bounds checking, really? How difficult is it to check buffer size before copying?
A little bit more difficult than not having to do it. And if you make writing secure code a little easier, it's a little more likely to happen.
E pluribus unum
If you don't have to think of it, then I'll bet I could audit your code and find you've made mistakes.
I've been programming C a long time, but I always double-check my buffers. Even if you do it perfectly, using a function that checks for you can save a line of typing. Not a bad thing.
"First they came for the slanderers and i said nothing."
Because, sometimes, you want to get out of bounds! Seriously, though, it's because it's not that simple, maintaining the good o'l efficiency.
Have you heard about SoylentNews?
Did you read the site ?
It is "C++11" , not "C11"
Do you guys mix the C standard with C++ ??
It's not about blame. It's about shutting down these exploits once and for all and making software safer. In case you haven't noticed, it's a hackers paradise out there.
It's always annoyed me that to declare a pointer to int, we write:
int *x;
which means "let x be that thing which, when de-referenced, is an integer" or more briefly "(*x) is an int".
[Anyone who thinks that it is really "int* x" (note the spacing) should consider what happens with "int* x,y" ]
So, let's have an explicit pointer declaration. I propose:
"&int x"
meaning "x is a variable of type address-of-integer".
How about not?
Contrary to the popular belief, there indeed is no God.
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
Then you can run cXXX. Oh wait, some new tld owner would sue.
You are being MICROattacked, from various angles, in a SOFT manner.
Isn't that's what compiler optimisation is for - removing code that has no effect?
The problem here is that the code has effect and isn't removed.
ALso, no bounds checking in the world is going to help you unless you write the code to handle what you should do when you are out of bounds. Bounds checking only goes as far as crashing you program earlier or hiding the problem. You still have to consider that it might happen and write the code necessary to handle it.
I write Hello World programs for a living. Here's some of my recent work:
char buffer[10];
sprintf(buffer,"Hello World");
They use buffers, but because they're well designed they never cSegment violation Address 0x401a35
At its core, C is designed to be a sort of portable assembly language. Most of its original features were intended to map directly to PDP-11 opcodes, and fortunately these proved to be generic enough that they could be implemented much the same way on other systems. (You'd be hard-pressed to find an architecture where the C construct ++var; didn't map to an increment opcode.) This is what makes C so great for when both portability and speed are necessary.
Unfortunately, it hasn't really kept up with the improvements in modern instruction sets. MMX dates back to 1996, and while many people first dismissed it as a gimmick, it proved to be the first of many such SIMD/vector instruction sets. Today, SSE/SSE2 and their successors are a mainstay, especially in applications like video and audio encoding/decoding. Other architectures like ARM also have their own SIMD instruction sets. But C does nothing to support this. There really ought to be SIMD data types and functions built in to the language, rather than having to rely upon compiler-specific extensions or inline assembly language.
Yes this is dangerous. Especially when someone will naively translate the "Hello World" into a language that require multiple byte UTF-8 character: the string will grow without notice.
This new C standard IS a different language, so you should be happy.
- Raynet --> .
Every time you make something foolproof they will invent a better fool.
Now you have to change the language once or blame the programmers forever
That's not how it works. You blame the programmers once and change the language forever. See ObjectiveC, C++, Java, C#, etc. for an example.
I suspect, though, due to the way you are writing and asking the question, that you've never worked on a large C code base (which if they know what they are doing are already taking the good ideas from OOP methodology - but don't need the "class" keyword as a mental crutch).
Hear hear!
If you look at what classes compile to, it's just structs and some syntactic sugar to automatically do what can be easily done manually to manipulate them.
The main advantage of using the C++ compiler, rather than doing it yourself, is not that the compiler automates the code generation for the manipulation. It's that the compiler always gets it right on what it does for you and can check much of what YOU do to be sure you don't violate intended encapsulation boundaries or point to the wrong thing (unless you use casts to tell it you really meant to do something risky). So there's less opportunity to write a bug and have the compiler accept it.
ANSI C incorporates some of this with strong type checking (which it got from C++). But a real C++ compiler can make-right-or-detect-error in more ways.
Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
If you look at what classes compile to, it's just structs and some syntactic sugar to automatically do what can be easily done manually to manipulate them.
Also some const vectors of pointers to functions. Like what you see in kernel driver tables.
Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
I just wish C would support default arguments. I write a lot of IO drivers and usually the same functions are used for both reads and writes, but some parameters are unused in certain directions. Right now, I just pass NULL, but I would really like to not even have to pass anything. There is a creative solution to the problem over at stackoverflow but it is a bit too much work for my simple cases.
http://stackoverflow.com/questions/1472138/c-default-arguments
Whoosh!
Count the number of characters in the string "Hello World".
All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
I have started looking at golang, and personally I wouldn't mind it taking over C. I realize it's a completely unrealistic scenario, and others will (strongly) disagree with me. But there you go.
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?
Just use snprintf instead of sprintf.
If BASIC was good enough for Jesus Christ, it's good enough for...oh, no, wait...
>> 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.
> only use bounded functions like strncpy() rather than unbounded ones like strcpy().
Use of strncpy() is one of those shibboleths I use to detect if a programmer knows what he's doing or not. If he uses strncpy(), he probably does *not* know what he's doing. He's probably been told by idiots like you that the version with the 'n' is safer, and then uses it without thinking, not even knowing that sometimes it doesn't even leave you with a valid C string. strncpy() is *never* the best solution to a problem. strlcpy() is frequently the best solution, but alas doesn't have enough traction in WG14.
Also FatPhil on SoylentNews, id 863
You're right in that strlcpy() may be better, however only if you fail to check return values, in which case you're already a lost cause.
It also doesn't excuse you for being rude and insulting.
And what's wrong with strncpy, which I started using heavily after a couple of years of working in C?
But there is an attitude problem with a lot of coders. For example, I almost *never* use while - 90+% of the time, I use for/next, so I have known limits.
Too bad so many schools DON'T teach error handling, and so much of upper management demands that programmers write what they want, when they want it, in the time they could wave their hands....
mark
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.
And what's wrong with strncpy, which I started using heavily after a couple of years of working in C?
But there is an attitude problem with a lot of coders. For example, I almost *never* use while - 90+% of the time, I use for/next, so I have known limits.
Too bad so many schools DON'T teach error handling, and so much of upper management demands that programmers write what they want, when they want it, in the time they could wave their hands....
mark
The problem with strncpy() is that it can leave you with a non-null terminated string which can cause problems later on if you're using a function that expects a null terminated string. So you end up having to manually check the size of the copied string to see if it was larger than your destination buffer minus 1 so you can warn someone that the whole string wasn't copied, or just you blindly terminate the last byte of the buffer to prevent problems later on.
Much safer to use strncpy_s() since it will null terminate the destination string automatically and you can check the return code to see if the entire string was copied or not.
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
errno_t strncpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n);
The strncpy_s function copies not more than n successive characters (characters that
follow a null character are not copied) from the array pointed to by s2 to the array
pointed to by s1. If no null character was copied from s2, then s1[n] is set to a null
character.
A zero return value implies that all of the requested characters from the string pointed to by s2 t
within the array pointed to by s1 and that the result in s1 is null terminated.
typedef int* intptr; done :).
Back in my day we programmed in binary by writing the program directly to the drive using a magnetized nail and that's the way we liked it. You young kids are gonna burn in hell with your newfangled built in bounds checking. Life is supposed to hurt damnit and if it doesn't hurt enough we have to MAKE it hurt. Now shut up while I clamp my balls in this vice!
If you hate the built in bounds checking so much, don't use the *_s functions.
See, now you are just twisting the whole "buffer" and "dynamically allocated memory" thing and just using whichever term when it suits you.
When I pointed out you where going from one to the other it was because you questioned me, asking how I thought printf("hello world\n"); uses any dynamic memory when I never said such a thing, I specifically said "buffer"
Not necessarily. I agree that simply guessing at the max size of a buffer is incorrect. But I think it is better to start out with a max guess with the option to calculate and adjust as needed. On most platforms it is more expensive to actually allocate new memory then to simply have one big allocated at program start chunk.
You shouldn't criticize a simple call to exit(), it is impossible to think up every single thing users will throw at your program. I think the best approach is to try and figure out the most common errors and create code that adjusts for them, then a generic handler that either calls exit() or returns and lets the calling function decide what to do based on the return value is a good catch all. Even then you arn't completely covered.
What about race conditions? Is it really better to try and hide the fact that data was incorrectly processed, or instead, having realized data is incorrect, calling exit() because it wouldn't make any sense to continue. (though we should try to avoid race conditions!)
What if I run:
yes $VERY_LONG_STRING | your_program
It just can't continue calculating the length of the string, at some point it has to say "this is too long" and exit.
I tend to stick with systems programming, I never got into hardware that much.
I completely agree with the second and third statement of your closing. However the first one, eh. I just don't see how functions like strncpy() are that big of a difference then how things where done before. It is perfectly possible to write code with strcpy() for example, and not leave openings for buffer overflows. I just feel like they are changing the language for the sake of changing it. And I also feel like the more functions like strncpy() that get pushed into the standard library, the closer we are to taking way the power that C gives you by doing what you asked for.
C++ has no intrinsic automatic memory management facilities. Not in the C++98 spec, not in TR1, not in C++11. The programmer can choose to encapsulate a pointer inside an auto_ptr or a shared_ptr or what-have-you, but it's not automatically done. Garbage collection isn't part of the spec and likely will never be.
Right, because for matrices foo.multiplyBy(bar.multiplyBy(baz.invert())) is so much easier to read than foo * bar * -baz. Operator overloading can certainly be used in stupid ways, but that's no reason to prohibit operator overloading.
It's worth noting that Java overloads operators left and right. Have you ever noticed that you can use "+" to add an int to a float, two ints, two floats, or to (gasp!) concatenate two strings?
Assuming arguendo that you're right (and you're not), is that a reason to prohibit inheritance? You yourself say there are areas where it's useful, so perhaps it should be included in the language for the benefit of programmers who are working in that domain.
Okay, so here it's really clear you've never used templates at all. Templates are typesafe. In fact, C++ templates are almost as typesafe as ML or Haskell. If the compiler can't unambiguously determine at compile-time what types are going to be used, that's a compilation error.
A lambda expression is just syntactic sugar for creating an anonymous struct. It uses the exact same "memory management" that every other variable declared on the stack does.
Listen, kid, I started writing C++ in 1989. Back then it was almost a decade old. It wouldn't get standardized until 1998. The first appendix didn't come along for five years after that, and the new revision of the standard was eight years later. In what bizarro world is this 'rushing into standardization'? If you want to say that about Ada83, go for it: yes, Ada83 was rushed and it shows. But the biggest complaint about the C++ standardization effort is that it's taken too long and the design committee is too conservative, not that it's been rushing headlong into things.
As an example, consider C++ concepts. Concepts were, are, a great way to resolve certain systemic shortcomings of C++. They got yanked from C++11 at the last possible minute despite being a fairly well-understood feature, because the committee wasn't quite sure the feature was mature enough for inclusion.
I can't tell if you're trolling or if you're just this badly ignorant of the C++ language. If the former, then have a nice day, I have been trolled. If the latter, I strongly urge that you spend a couple of years writing code in C++ and discovering the breadth and depth of the language. You might, like me, find yourself liking it an awful lot.
>> But I think it is better to start out with a max guess with the option to calculate and adjust as needed.
Not at all. You should NEVER guess first then readjust. ugh that idea sucks balls.
I agree you may need to define a practical limit but you should use the same limit in both the buffer size calculation and the read operation (or whatever) that fills it (which is where and why functions like stricpy() and strncpy() have value over strcpy() ). That way you don't need to ever worry about crashing the buffer or dynamically resizing it. You also need to share any limitation as a design constraint with the users/callers of your code.
>> You shouldn't criticize a simple call to exit(),
I will when the need for it to even exist is retarded, as it is simply being used to handle failures caused by bad programming approach rather than a lack or failure of system resources.
>> What about race conditions? Is it really better to try and hide the fact that data was incorrectly processed,
OK what race condition are you expecting in hello world?
You're just trying to muddy the water by bringing in multi-threaded or multi-process issues, but to answer it anyway, if the environment is multi-threaded you should be using the appropriate locking or synchronisation mechanism (e.g. semaphores, mutexes, critical sections, events etc) around the shared resource to completely prevent race conditions.
..then Socialism would actually work !!
The ability to have safe arrays (and safe pointers ?), which you can selectively turn off - that would be a great improvement. Typically, 20% of your code make for 80% of execution time. For the 80% scarcely used code, it would be good to have bounds checking turned on by default.