Domain: open-std.org
Stories and comments across the archive that link to open-std.org.
Comments · 133
-
Re: safe string copy?
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. -
Re:Who needs threads?
IIRC it's because without putting explicit constraints on the memory model (needed for threading), you end up with holes of varying sizes when talking to memory from threads.
It's mostly to do with CPU caching / memory barriers and having a consistent temporal view of data in and out.
If it's not in the language, you end up with each platform/compiler having their own approach to barriers / atomics which makes glueing different bits of code together with different approaches a crap shoot when it comes to consistency.
-
Re:C?
Well, C++11 is irrelevant to what I was saying, but after double-checking about C11, you're right. The ISO WG14 home page confused me. It says, "The current C programming language standard ISO/IEC 9899 was adopted by ISO and IEC in 1999. Technical corrigenda TC1, TC2, and TC3 were approved followingly, TC2 in 2004, TC3 in 2007." (Emphasis mine.) Apparently, they need to update that page. 9899:2011 is available from ISO here.
So much for the claim that C is in any way more "last century" than C++. Thanks for the tip.
(Curiously, GCC includes experimental support for C++11, but has almost no mention of C11 anywhere.)
-
Re:In practice it's like a different language.
So what?
I think he simply claimed that you have to deal with C++ written by C programmers all too often. That's my experience, too.
STL isn't suited for all possible uses, sometimes you need your own string and container classes.
I don't see what that has to do with the above. I suppose there are some rare cases where the standard library isn't appropriate, but are you arguing this is an excuse *never* to use it?
By the way, your reference seems severely dated. Some of its complaints are still valid, but seem based on the state of STL support ten years ago.
-
Re:In practice it's like a different language.
As if those were the worst problems. And allocating memory dynamically fragments it. Ever tried writing custom allocators for STL to avoid dynamic memory allocations (or do them thru your own memory manager)? Good luck and hope you are tolerant to rectal pain.
-
Re:In practice it's like a different language.
So what? STL isn't suited for all possible uses, sometimes you need your own string and container classes.
Don't be a zealot, pragmatic programmer should find the right trade-off between reusing code and writing an optimal one for a specific problem/area. Nothing can be optimal in all cases - sometimes you need to be as close to hardware as possible at the expense of unreadable/inflexible code (for me, those are the most interesting and challenging areas), and sometimes you only care about maintainability of your code by a disposable programming drone. -
Re:So...As with every other version of the C standard, you can read the draft yourself. A few things that are nice:
- A detailed and well-thought-out set of atomic operations. I've got a diff for clang that implements these that should be committed in the next few days after a bit of tidying. Ed Schouten has written the supporting header to FreeBSD libc, so these can be used now (with fall back to GCC intrinsics for a marginally slower implementation).
- Unicode string literals and a few functions for manipulating them.
- _Generic() letting you write type-generic macros.
- Anonymous structure and union members, so you can write things like struct { int tag; union { void *ptr; uintptr_t i}; } s; and then refer to s.ptr or s.i, rather than needing to provide a name for the union (this is already a GNU extension, but it's nice to have it in the standard).
- Static assertions, so you can do things like _Static_assert(sizeof(int) == 4, "This code path should not be used in ILP64 platforms!"); and get a compile-time error if it is.
- A _Thread_local storage qualifier for thread-local variables (equivalent to the __thread GNU extension).
- Alignment checks and specifiers.
- A few things from POSIX, like the x specifier in fopen() for exclusive open.
Some of the not-so-nice features include threads.h, which is equivalent to pthreads but with a different function names (and ones that seem quite likely to cause conflicts with existing code).
-
Draft available for free
For those interested, the last draft before the official version is available for free here: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
-
Re:Oh dear.
Um...you can. Thus the whole bit about capture lists. std::function is your friend.
No, you can't -- not when it would matter for C++ lambdas to be equivalent to other language's closures. The "while bit about capture lists" is there, in part, to specify exactly when you can.
From the standard, pages 89-90:
If one or more names in the effective capture set are preceded by &, the effect of invoking a closure object or a copy after the innermost block scope of the context of the lambda expression has been exited is undefined.
So, when the lambda actually "closes over" a variable (not just capturing its value), you can't use it outside the block where it was defined. That's unsurprising, since it would mean keeping the stack alive or "lifting" the variable from the stack into the heap, which would open a whole new can of worms.
-
Re:Design by commitee vs. design by guru
That trick only works in a few contexts, ones where the array size is known at compile time, has not yet been lost by the language and "sizeof" will still work.
C/C++ arrays are inherently compile-time, with size being part of the type (which is a compile time construct). That's why there's std::vector in C++.
If you pass the array through to another function, the size is lost.
If you use the trick as quoted, you can pass the array through several functions easily. The real problem is that you can't store it (in a global or a field), since type of the variable would have to be in scope of template as well.
I've no idea what the compiler is supposed to do for your C99 snippet, as C99 is not part of C++ standard. If the compiler implements such a weird mix (I don't think anyone does; would g++ permit VLAs in
.cpp files?), it's entirely implementation-defined.I once proposed generalizing the C99 feature of allowing dynamically sized arrays at the language level to allowing a similar syntax in all array-related contexts.
This has the same fundamental problems as C99 VLA themselves - it introduces a runtime component to the type system, which is inherently compile-time. In C99, the breakage is most immediately seen by the fact that type system does not actually verify that you pass correct size in. For example:
void foo(int n, int a[n]);
int a[3];
foo(3, a); // correct,
foo(10, a); // incorrect, but compiler won't catch itMore generally, C99 VLAs, on type system level, are some kind of a weird type where length is "not directly known, but there is an associated value" - so you get types with attached (runtime) values etc.
Anyway, in C++ today you just use std::vector and don't care about all this. The only downside there is that it's always heap-allocated, whereas C99 VLAs can be stack-allocated. In theory a smart compiler could actually figure out where this is permissible, but it's very tricky - it has to consider operations which require heap allocation (resize, move, swap), use of allocators, specializations of std::allocator, and overloaded operator new/delete. No-one actually does that in practice.
Now, it would actually help a lot if we had a separate type which only has those operations available on it which permit stack-allocated implementation. Compilers could then provide a straightforward "pixie dust" implementation for that type when used for an auto local, just as efficient as C99 VLAs (but with size being part of the array, and the whole arrangement thus being actually memory-safe, with no possibility to pass an incorrect size), as a matter of quality of implementation. A standard proposal for this exists, calling such a type std::dynarray. So far as I know, it is being considered as part of C++ TR2. If it passes, it would, in my opinion, be the best solution to the problem.
If subscript checks are implemented in templates, though, the compiler has to execute them every time
I'm not sure what you mean by this. A function template, once instantiated, is a function like any other, and any template parameters become simple constants in the instantiation. If you call such a function in a loop, then it's up to the compiler to inline it (and then hoist the check) or not, but this is the same for both template and non-template functions.
-
Re:Like a zombie
The most recent mailing had a paper requesting to remove them - did it not pass the vote for FDIS?
-
Re:Header files again??
No, they haven't got rid of header files yet. There was a proposal which didn't make it for C++0x, but will likely be strongly considered for TR2.
-
Re:Still no designated initializers
Yes, VLAs are useful to get the extra perf edge from stack allocations (and consequent lack of deallocations). The problem is that naively specified VLAs make the type system very messy, as evident in C99. Nor are they trivial to use; I mean, take C99 again:
int foo(int n, int a[n]);
...
int a[3];
foo(sizeof a, a);Looks good, but there's absolutely nothing preventing the caller from passing in a wrong size - it's just U.B. if he does. So for VLAs the size of array is not part of the type, despite it being right there in the declarator. And yet it's magically tied to the array in question, since you can do sizeof(a) etc.
For C++, there has been some talk for adding a VLA-like type to TR2 (which will come after C++0x is finalized). The idea is to make it a library type, std::dynarray, somewhat more constrained than vector (e.g. no resize or operator=), such that the compilers would be able to implement it as VLA as a matter of quality-of-implementation. So someone (say, Boost) can provide a pure library heap-allocating version as a universally supported baseline, and then specific implementations can optimize it to their heart's content.
-
Re:My first question.
Seems to be N2909, revised as N2923, and voted into the draft in July 2009.
On a side note, the new std::forward_list does not have size() at all, so for those scenarios where having size is superfluous (either because you don't want to pay the overhead of an extra size_t for an empty list, or because you want to splice ranges), you can use forward_list for best performance.
-
Re:My first question.
Seems to be N2909, revised as N2923, and voted into the draft in July 2009.
On a side note, the new std::forward_list does not have size() at all, so for those scenarios where having size is superfluous (either because you don't want to pay the overhead of an extra size_t for an empty list, or because you want to splice ranges), you can use forward_list for best performance.
-
Re:My first question.
Seems to be N2909, revised as N2923, and voted into the draft in July 2009.
On a side note, the new std::forward_list does not have size() at all, so for those scenarios where having size is superfluous (either because you don't want to pay the overhead of an extra size_t for an empty list, or because you want to splice ranges), you can use forward_list for best performance.
-
Re:Just C.
And then this: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
-
Re:What about C++?
C++ has an astonishingly complicated grammar, which means that compilation takes forever and other tools don't work as well as they do for languages with simpler grammars, like C or Java.
Modern c++ compilers are extremely fast; not as fast as Java compilers, but considering they do much more many things (templates for example), then they are quite fast. They are so fast that compiling large code bases with them is extremely viable, and it's a task done everyday by millions of developers.
C++ doesn't really have compile-time encapsulation: if you add a private member to a class, you need to recompile everything that uses that class even though the class's public interface didn't change. That woudn't be so bad in and of itself except that C++, again, takes forever to compile.
How is that a big problem? you make it sound like it's a colossal problem, but in reality, it's not. Unless your class is used by every other class or function, the recompilation is minimal. The benefit of this is that you can use value classes in c++, whereas in Java you can't, every class is by reference, which is stupid.
C++ also doesn't have run-time encapsulation or really any serious run-time error checking that you don't do yourself. Yes, it's for performance reasons, but some people are working on problems that aren't performance-critical and would prefer a language that doesn't pound nails through our dicks. (if it doesn't have encapsulation, why do they call it "object oriented?")
If you refer to arrays, vector::at() is your friend. If you are not disciplined enough to use it, then you don't belong in programming. You can even use smart pointer classes that throw a null pointer exception, if you really want it. In any case, it's not anything like you say it is.
1) If you've allocated some memory for an object, and then you throw an exception, you don't have that pointer anymore, and because C++ doesn't have garbage collection you've just leaked memory. The only way around this is to implement garbage collection yourself; C++ weenies call this "RAII" and if they're really far down the rabbit hole they sometimes don't even realize that it's just them implementing shitty reference-counting garbage collection.
RAII is actually superior to Java's garbage collection. It's much more critical for big applications to release as much memory as possible upfront.
2) You can't throw exceptions in destructors. Well, you can, but when an exception is raised, all the destructor for objects on the stack are called, and if one of them throws an exception while you're already handling an exception the program terminates. Seriously, that's what the standard says, I'm not making this up. So you can't throw exceptions in destructors, or call any function that might throw an exception.
How is that even a problem? Java's unpredictable finalization order is way more of a problem.
3) In every major compiler I've used, exception handling support is implemented in such a way that it slows down every function call you make. Yes, it's only slightly, but it means if you really care about performance, you can't use exceptions, and if you don't care about performance why the hell are you using C++?
Read this first: http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf Exception handling has a cost only if there are non-trivial destructors to execute. Since C++ allocates most objects statically, the performance cost is factored into the program as if no exception was thrown. On the other hand, in Java, you pay the price in garbage collection.
And even if you want to use them they're almost worthless; I mean you can't even get a goddamn stack trace out of them.
True, but you can have other meaningful information, such as the file
-
Re:I'll explain oppressive development environment
First of all, thank you. It's always good to hear some criticism on definite and specific issues, rather than the generic "M$ sucks".
(I am a VS developer)
Or how about, starting in either VS2005 or 2008 (can't remember which one), I opened up a project written in VC++6 and freaked when I suddenly started seeing hundred and hundreds of warnings, telling me that functions like strncat() (strncat!) were "unsafe" and I should use something like _strnscat or something like that, which supposedly was "more" safe at the cost of being totally Microsoft-specific.
It was added in VS2005, but it's not quite MS-specific. OpenWatcom also provides it out of the box, and there's a cross-platform FOSS implementation available now.
The reason why the text says that they are unsafe is because, frankly, they are - as a result of several security studies, they account for a very significant proportion of known buffer overrun vulnerabilities. Of course, it's perfectly possible to use them in a safe way, but surprisingly many people actually do... but this take has been fairly controversial, anyway, I won't deny that.
It should also be noted that this isn't actually the default for the compiler as such - if you directly do "cl.exe foo.cpp", you won't get any warnings for strcpy. It only pops up if you raise the warning level to
/W3 or higher, which is what IDE does by default for newly created C++ projects. The text of the warning also clearly states what to do to get rid of it:warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use CRT_SECURE_NO_WARNINGS. See online help for details.
When you refer to it being per-project, do you imply that it was inconvenient to add the define to all the numerous projects you've had in the solution?
How about the auto-hide windows that seem to randomly decide to suddenly be pinned or to suddenly appear during unrelated actions?
Tool windows in VS have different and separate settings depending on which mode you're in - aside from the default one which you get on normal VS start and/or project open, debugging is a separate mode, and opening VS with a single file (aka "simple editing") is yet another. This is somewhat similar to Eclipse perspectives.
If you pinned a toolwindow in one of those modes, it will not be pinned in other modes. The idea is that you generally want different toolwindow configurations depending on activity - e.g. you might want Breakpoints window to be set to auto-hide during normal editing, but pinned in debugging. So you will, at most, need to pin the window in all modes in which you've made it visible, and most likely, you'll be dealing with just the default mode and the debugging one.
If you experience random pinning/unpinning that cannot be explained by the above, then please describe the scenario under which it happens - which toolwindow, what were you doing when it got unpinned, etc. Better yet, do it in a bug tracker.
When working with C#, the compiler and editor will give you a red squiggle under code it can't compile, but gives you know way to know where or how many places in the file they are
If you open the Error tool window (which will happen after the first build, but you can do it manually), it will list all IntelliSense errors just as if they were compiler errors, so you can see the error descriptions, and double-click to jump to location. By the way, this (as well as squiggles themselves) also works for C++ in VS2010.
If you want margin markers as in Eclipse, you can
-
Re:Objects...
Only if you silently return 0 in allocate(). Which is fairly bone-headed, to be honest. You can see how EA created their own OOM-aware nothrow allocators in their STL implementation.
-
Re:Objects...
That's not the fault of the feature itself, but of people using it incorrectly (at least in a particular environment).
It is still quite possible to retain full control over template instantiation by splitting template into header & implementation files (with header only containing function declarations and not definitions, and implementation containing their definitions), using extern template in the header for all specializations that you need, and using explicit instantiations in the implementation file for those same specializations. That way, any attempt to implicitly specialize the template will fail with a linker error will fail due to missing function bodies - and you still retain the convenience of code reuse, even though it's more explicit now.
-
Re:Maybe they've grown up a bit
It's not hard to surpass the performance of most STL solutions. See EASTL, EA's version of STL written specifically for games requiring high performance. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html And as another simple example, the associative hashtable container in TR1/C++0x standard libraries (unordered_map) uses chaining for resolving hash-table conflicts, but you could write an alternative that uses open addressing that would be faster in numerous occasions where you don't need to preserve iterator validity across hash table resizing, and the key/value object size is relatively small (no more than a few machine words each). That said, STL overall is pretty decent, it usually has better performance than a lot of this stuff I've seen people do in C. Many C coders use hand written linked lists instead of using a data structure more suited to the task at hand, such as a balanced search tree or hash table when needing to perform a lot of searches across a data set.
-
Re:Maybe they've grown up a bit
In testing, performance can be 4x SLOWER with the stl than by using c99. Variable-length arrays combined with bsearch make for one of the fastest look-up "containers" going - way faster than any stl algorithm.
This myth has been repeated to death thousands of times over the years, and disproven on nearly every occasion. Every micro-optimization C++ newbie thinks they can prove that the C++ STL results in slow code. Ultimately, the cause for his results are of writing inoptimal code.
But it seems you didn't even get that far. From what I gather from your post, I'd guess the last time you used C++ to be sometime near the year 2000. Maybe you should check again; C++ compilers have advanced much since then in many respects.
As the STL is good enough for many game developers, I heavily doubt you have the experience to prove it is actually slower. You can read about EA's inconclusive experiments in their EASTL paper. EA's replacement STL provides more efficient container allocators -- allocator replacement is a feature of the STL and something all C++ programmers do at one point -- and mainly optimizes the STL for console C++ compiler deficiences (usually poor templating support).
c++ has its uses. It has nice features. The stl, on the other hand, is visually offensive. I bought the hardcover TR1 spec, read it twice, and consider it a waste of time and money. For what most people need, if they can't write their own classes, there's enough generic code that they can modify to achieve their goals.
On top of which, object-oriented programming is a paradigm, not a language feature. You can do OOP in c just fine by passing an explicit "this" as the first parameter in any function you want to act like a method call. You can even do OOP in assembler - Borland had some nice material on that.
Use c++ for encapsulation, for references, for the syntactic sugar - but not because the stl will make it run faster - it won't.
No one cares about OOP in C++ anymore. C++ truly has no advantages for it. C++'s unmatched advantages (except for in D) are in compile-time metaprogramming, or generic programming. As you are citing the STL, you should understand this. If the STL were written in terms of runtime polymorphism, it would be much slower due to no longer generating C-optimal code.
-
Re:Maybe I'm missing something
They're a confirmed feature in C++0x. g++ and VC2010 both support 'em. Take a look at section 5.1.2 in the current draft spec:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf -
Re:Just like the other vendors
VLAs have no "easy fix" -- the closest alternative is alloca(), which my manpage claims is "buggy" on many unspecified systems, and of course, it's not really portable or standard either. Using malloc() is slower, uglier (since if you're doing it right you'll want to check the return value), and has the potential to fragment your memory.
alloca() is actually decent option on all mainstream architectures - the problems appear only when you delve into really exotic stuff. It can be easily broken when implemented as a true function (playing tricks with the stack pointer), but that same gcc actually implements it as an intrinsic (i.e. the output just directly adjusts the stack pointer as needed) pretty much everywhere. That is rather foolproof. If you go by the basic rule of thumb of only ever using it in a variable initialization (which is consistent with limitations of VLAs), it can't really go wrong.
I imagine that we will get something comparable (but standardized) in VC++ when it gets into C++ - e.g. the std::dynarray proposal. They'll have to wrap up C++11 first, though...
Anyway, IMO, main benefit of VLAs isn't even in dynamic stack allocation - it's rather in painless handling of dynamically sized arrays, especially multidimensional ones, when passing them as arguments, e.g.:
void foo(int w, int h, float a[w][h]) {
a[3][4] = 1;
}In C90, since you can only get a pointer through, you have to do all addressing arithmetic by yourself:
void foo(int w, int h, float* a) {
a[3 * h + 4] = 1;
}The verbosity increases exponentially as more dimensions are added, while VLA solution takes care of all that automagically.
Yeah, I don't really see a fix for that short of supporting them on the level of type system, one way or another. I'm not aware of any proposals to have something similar in C++, either (though there, of course, you'd likely just do a heap allocation, and wrap the arithmetic in a class, like boost::multi_array).
-
Re:OMGWTFPDF
I've never understood the logic of viewing PDF's inside the browser via plugin; I can understand it for flash or java, where they provide certain functionalities and integrate within the web page, but don't see why you'd want to use a PDF in-browser, which doesn't integrate with the rest of the site.
It depends on the nature of the PDF. If it's a long windy document, then sure, I'll download it and read it separately. But, for example, a lot of C++0x papers are small (1-5 pages) PDFs, and when reading comp.std.c++, I have to view some random ones all the time. It doesn't make any sense to download them just for one view, and I never know when (and if) I'd need to view that one again. It's so much easier to just open the list, pick the paper I want, and have it open right there and then in the same window.
-
Re:When will we change programming practices?
It seems that all exploits that I've read about over the last decade all boil down to the same flaws - buffer overflows, invalid pointers, format strings, etc.
Yet, developers persist in using the same old programming languages & libraries that are rife with weaknesses.
Why haven't they changed to something better?They did. A few examples for Microsoft in particular, listed in no specific order:
-
.NET and C#/VB are memory-safe (though you can explicitly opt out in C# with "unsafe" code).
- StrSafe - C
- ISO C TR 24731 aka "Secure CRT" - C
- checked STL containers and iterators (bounds checking, iterator invalidation etc) - C++The problem is that any memory-unsafe language (which both C and C++ are) has ways to work around any such library, and writing everything in a high-level language/framework (such as C#/.NET) is unfeasible because of performance requirements, and the sheer volume of existing C/C++ code. That said, there clearly is a trend of using higher-level languages and frameworks for new developments: any
.NET language on Windows, Python or Ruby on Linux, Java mostly for internal corporate applications on various Unix flavors, etc; with only the perf-critical code parts implemented in C/C++ and called via FFI of high-level language used. -
Re:Maybe the vendors don't want C++...
The standard docs pretty clearly state that the default error hander does nothing and returns to the function, and that the strcpy_s function truncates the buffer and then returns after the error handler returns.
Okay, let's try this again. Here is the most recent draft. Look at 6.6.1.1 "The set_constraint_handler_s function", paragraphs 2 and 4. Here's what it says:
2 The set_constraint_handler_s function sets the runtime-constraint handler to be handler. The runtime-constraint handler is the function to be called when a library function detects a runtime-constraint violation. Only the most recent handler registered with set_constraint_handler_s is called when a runtime-constraint violation
occurs.4 The implementation has a default constraint handler that is used if no calls to the set_constraint_handler_s function have been made. The behavior of the default handler is implementation-defined, and it may cause the program to exit or abort.
And also 6.1.4 "Runtime constraint violations":
2 Implementations shall verify that the runtime-constraints for a function are not violated by the program. If a runtime-constraint is violated, the implementation shall call the currently registered runtime-constraint handler (see set_constraint_handler_s in ). Multiple runtime-constraint violations in the same call to a library function result in only one call to the runtime-constraint handler. It is unspecified which one of the multiple runtime-constraint violations cause the handler to be called.
3 If the runtime-constraints section for a function states an action to be performed when a
runtime-constraint violation occurs, the function shall perform the action before calling the runtime-constraint handler. If the runtime-constraints section lists actions that are prohibited when a runtime-constraint violation occurs, then such actions are prohibited to the function both before calling the handler and after the handler returns.4 The runtime-constraint handler might not return. If the handler does return, the library function whose runtime-constraint was violated shall return some indication of failure as given by the returns section in the functionâ(TM)s specification.
I hope this is clear enough. I expect that you've just looked at the individual description of strcpy_s, and didn't find anything about runtime violations; but the paragraphs cited above apply to all functions for which there's a "runtime constraints" section.
I never actually tried calling these things as I want to write portable software.
But you do use strlcpy. I don't see how this is any different - in both cases, if you want to be portable, you have to use a third-party implementation on all platforms where this functionality isn't available out of the box (as neither is included in the base standard for the language). And yes, there is an independent, open-source (MIT license), cross-platform implementation of TR 24731 - the Safe C Library.
Anyway I don't see how a DOS is much better than a buffer overflow.
Well, it's obvious - a buffer overflow is a potential high-risk security exploit, while a DoS is just a DoS.
Anyway, the philosophy is that if there is a problem in your application, it should be made obvious as early as possible. With strlcat, there are all kinds of interesting possibilities - perhaps someone used it but didn't check the error code, and, in fact, didn't bother to handle the truncation case specially at all. Depending on the circumstances, this may lead to a crash or other form of DoS down the line (e.g. when trying to parse the buffer expecting well-formed data, since it was already validated before the call to strlcat), but worse, it may lead to silent wrong behavior - imagine trun
-
Re:Maybe the vendors don't want C++...
The standard docs pretty clearly state that the default error hander does nothing and returns to the function, and that the strcpy_s function truncates the buffer and then returns after the error handler returns.
http://www.open-std.org/jtc1/sc22/wg14/www/projects#24731
I never actually tried calling these things as I want to write portable software.
Anyway I don't see how a DOS is much better than a buffer overflow.
-
Re:BIG need to dramatize
Concepts in C++ should have had the same effect for Generic Programming in C++ that C++ had for Object Oriented Programming in C. The should have democratized generic programming and brought forth a renaissance in C++ library design. Instead, petty politics killed the most exciting change to C-like languages in years.
I think you're overstating things a bit. It's certainly true that Concepts would have been an improvement, and would have made life a whole lot easier for a whole lot of people -- but let's face it, "renaissance" implies that we're currently in a dark age, and that's overstating things quite a bit. Point one, there's pretty substantial work being done right now. Point two, concepts are not going to allow an average programmer to just decide that they're going to recreate something like Spirit or Proto or Xpressive this afternoon, or anything like that.
I also the think "petty politics" is going overboard, at best. Howard Hinnant seems to have been the one who started the discussion at the last meeting that ultimately led to the removal of concepts from the draft standard -- and I find an accusation of his being involved with petty politics completely unbelievable. Quite the contrary, the (admittedly few) times I've talked with him, he struck me as a very level-headed person who was careful to evaluate ideas on their merits. Likewise, Beman Dawes, Bjarne himself, and (since you brought him up) Dave Abrahams don't seem to me exactly "petty politics" kinds of people either.
I'd also note that when it came to a vote, the overwhelming majority of committee members voted to remove them -- including (for one example) Douglas Gregor, the primary author of ConceptGCC, and one of the coauthors of both N1758 and N1849 (the two versions of the Indiana Proposal).
I think the vast majority of the committee simply believed that including concepts would delay the standard by a minimum of a couple years, and probably longer than that. A fair number of features originally intended to be included in C++0x have been removed for exactly the same reason, though quite a few others have localized enough effects that they're currently scheduled for a TR (Technical Report) rather than waiting for the next major update to the standard itself. Unfortunately, since they make fundamental changes to the type system, I don't think concepts can be added in the same way.
*(Dave - I mean that in the nicest sense... you've done a great job with Boost (oh, we need to jam again, too)).
I object your honor. Everybody knows a proper blues guitarist is short and fat, with black hair and a scraggly beard -- and this "Dave" is about as different from that as humanly possible! :-) -
Re:BIG need to dramatize
Concepts in C++ should have had the same effect for Generic Programming in C++ that C++ had for Object Oriented Programming in C. The should have democratized generic programming and brought forth a renaissance in C++ library design. Instead, petty politics killed the most exciting change to C-like languages in years.
I think you're overstating things a bit. It's certainly true that Concepts would have been an improvement, and would have made life a whole lot easier for a whole lot of people -- but let's face it, "renaissance" implies that we're currently in a dark age, and that's overstating things quite a bit. Point one, there's pretty substantial work being done right now. Point two, concepts are not going to allow an average programmer to just decide that they're going to recreate something like Spirit or Proto or Xpressive this afternoon, or anything like that.
I also the think "petty politics" is going overboard, at best. Howard Hinnant seems to have been the one who started the discussion at the last meeting that ultimately led to the removal of concepts from the draft standard -- and I find an accusation of his being involved with petty politics completely unbelievable. Quite the contrary, the (admittedly few) times I've talked with him, he struck me as a very level-headed person who was careful to evaluate ideas on their merits. Likewise, Beman Dawes, Bjarne himself, and (since you brought him up) Dave Abrahams don't seem to me exactly "petty politics" kinds of people either.
I'd also note that when it came to a vote, the overwhelming majority of committee members voted to remove them -- including (for one example) Douglas Gregor, the primary author of ConceptGCC, and one of the coauthors of both N1758 and N1849 (the two versions of the Indiana Proposal).
I think the vast majority of the committee simply believed that including concepts would delay the standard by a minimum of a couple years, and probably longer than that. A fair number of features originally intended to be included in C++0x have been removed for exactly the same reason, though quite a few others have localized enough effects that they're currently scheduled for a TR (Technical Report) rather than waiting for the next major update to the standard itself. Unfortunately, since they make fundamental changes to the type system, I don't think concepts can be added in the same way.
*(Dave - I mean that in the nicest sense... you've done a great job with Boost (oh, we need to jam again, too)).
I object your honor. Everybody knows a proper blues guitarist is short and fat, with black hair and a scraggly beard -- and this "Dave" is about as different from that as humanly possible! :-) -
Re:Concepts aren't enough!
Disclaimer: I only read the first two sentences.
Click here and look for the word "axiom". :) -
Re:Maybe the vendors don't want C++...
They've made it that unless you #define a load of stuff to switch the crap off or start using proprietary Windows extensions none of your code will compile without warnings.
They deprecated huge chunks of both the C and C++ standards without asking any of the standards committees.
I assume that you refer to the so-called "secure CRT" functions here, such as strcat_s. If so, there are two points to be made.
First of all, those aren't proprietary extensions. It's an implementation of an ISO C++ TR 24731 (as most ISO standards, an electronic version of the final standard isn't available freely, but you can look at the final draft). Yes, the implementation in VC2005 preceded the final release of that TR, and rather went hand in hand with development of the spec; but virtually all C++ compilers did that for ISO C++ itself as well, before it was finalized in 1998.
Regarding "deprecating", it's mostly a poor choice of words. The compiler would complain about "strcpy is deprecated", but it was never supposed to mean deprecation in ISO C++ standardeze meaning. Besides, it was a warning, not an error, and a conformant C++ implementation can produce all kinds of warnings so long as it compiles legal code - warnings are not regulated by the Standard in any way. In any case, you don't need to "#define a load of stuff" - as with any compiler, you can pass preprocessor definitions via compiler switches from command line (or makefile), and you only need a single define - _CRT_SECURE_NO_WARNINGS.
Oh, and they *still* haven't caught up with C99.
No-one has caught up with C99 yet. Even gcc still has quite a few features implemented only halfway, or even outright broken. Heck, VLAs - which is one major C99 feature - were still broken in gcc 4.3, and only properly supported in 4.4. If anything, this just points out how little people do care about most C99 stuff (which you know anyway if you actually follow the discussions on the matter).
At the same time, VC++ supports C++ TR1, which has some more useful bits of C99 (such as stdint.h header with standard typedefs for things such as int32_t).
-
Not a bombshell
It's not a bombshell by a long measure. Anyone who had been tracking C++0x standardization process (reading comp.std.c++, and WG papers) knows that the goal of getting the standard out by 2010 was fairly unrealistic, mostly because of concepts. The joke that "x" in C++0x is actually a hex digit and not decimal has been around for several years now.
-
Not a bombshell
It's not a bombshell by a long measure. Anyone who had been tracking C++0x standardization process (reading comp.std.c++, and WG papers) knows that the goal of getting the standard out by 2010 was fairly unrealistic, mostly because of concepts. The joke that "x" in C++0x is actually a hex digit and not decimal has been around for several years now.
-
Re:Wait, what?
Other than this:
-
Re:Flat Earth
SQL is actually a pretty damned good, single-purpose language.
I disagree. SQL is actually a rather crappy language for what it does - unnecessarily verbose, lots of weird corner cases and exceptions, very unobvious solutions to some rather common problems, etc. In comparison, something like Date's language (as implemented in e.g. Suneido) is far cleaner...
C is also a crappy language. It has messy grammar, hard both for humans to read and for compilers to parse (a feat oonly surpassed by C++ and Perl), necessitating tools for something that really shouldn't require one. It has some totally unused and pointless features, such as separate namespaces for structs/unions/enums, or the "auto" keyword. It has weird unsigned arithmetic rules. You can write code in it that put Perl to shame. Truly, Modula-2 is a far better system programming language...
But here's the thing. Everyone knows C. There are dozens of compilers, IDEs and associated tools - every platform has one targeting it. There are hundreds of books and thousands of tutorials, and millions of programmers who know it. C API and ABI are de facto standards for reusable libraries and FFI. All this because, really, C is good enough. It may be messy, but it does mostly everything that needs doing. And in areas where it doesn't do so good, it's easier to extend it than reinvent the wheel.
Same mostly goes for SQL. It's a mammoth spec now, very complicated and not truly implemented by anyone. But the real-world subset works. For all the quirks you have to learn, it does the job, and most SQL skills actually do transfer between implementations. Again, where there are pain points that are just too inconvenient it's easier to extend the language (and, hopefully, eventually standardize such extensions) than to start from scratch.
-
Re:But it could be!
there are no guarantee that destructors on static object will be called.
Actually, Section 3.6.3p1 of the C++ standard guarantees it. (Wonder why people who can't validate technical language claims feel qualified to mod posts that make them).
-
Re:The wole thing is just a bunch of nonsense
Firstly, the specification of C anf C++ standard library is governed by the corresponding standard commitee.
-
Re:When will MS learn?
This is not the first time MS has done this. They have plenty of other standard functions that they have deprecated.
Yes, you read that right. Microsoft is deprecating parts of an ISO Standard all by themselves.
No, Microsoft isn't deprecating "parts of an ISO Standard" - only the standard committee can do that, by marking those parts as deprecated in the next version of the standard. Microsoft has enabled warnings on use of those "unsafe" functions by default, yes, but it is very much not the same thing.
Regarding "all by themselves" part - do you realize that all those "safe" *_s functions are actually covered by an ISO C99 TR?. There's also a FOSS implementation available under the MIT license.
And the warnings are irritating. You can't write a nice cross-platform library without either spewing tons of warnings or having to put in a bunch of #defines to shut the compiler up.
You don't have to use #defines for that purpose, you use compiler flags in your makefile. You'll have to write one specifically for MSVC anyway (since it uses its own Make), so it's not a big deal.
And if you do that, your users get irritated if they depend on these warnings because you just turned them off
That doesn't make sense. If you turn them off for the code of your library, they're obviously not turned off for code of your users - unless you put #defines in your headers, which is obviously a dumb thing to do for many reasons (and I've already explained the proper way to do this above).
-
Re:They should go one better...
Seriously though, how is it supposed to make your code safer if you pass the size you think your destination buffer is?
Quite often when using memcpy you actually do know the size of your destination buffer - it's sizeof(buffer), when it's an array.
On the other hand, it's fairly easy to forget that the buffer is actually of limited size, which may be less than the size of the data you're copying over. This is supposed to catch these kinds of things, nothing more.
Also, what happened to the __restrict keyword?
And what should happen to it? There is no such thing in the C++ standard, and MSVC is a C89 & C++03 implementation. It's definitely not a C99 implementation, and that isn't even claimed (I don't think it even implements a single C99 feature apart from
// comments - it won't even let you put variable declarations between statements in .c files).By the way, all those safe *_s functions actually come from an ISO TR for C99 - here is the PDF of the spec. Now that thing is specifically for C99, so it has "restrict" in all the proper places.
-
Re:secure C functions (_s)
I understand that the _s functions were first implemented in MS's CRT implementation, but they're hardly Microsoft-specific. Remember, before C itself was an ANSII standard (subsequently ISO etc) it was a "AT&T specific" programming language. Advancing the state of the art is hardly anti-competitive. I'm not sure what the current state of the ISO standard is, but the _s set of functions have been standardized and are making their way in. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1225.pdf
-
Re:Does Ballmer really want the answer
The Win32 api certainly does accept forward slashes just fine. The problem is appliations and clueless programmers that don't think files ever contain forward slashes. Generally you cannot cut & paste or drag & drop or type in a filename with forward slashes into many applications, and operation system calls like getcwd cannot return strings with forward slashes without them crashing. What I want Microsoft to do is insist that the programs should all accept and work with these, or they don't get the "windows certified" label or something. I am really sick and tired of having to add tons of code to decide whether a piece of text is a filename or not and disabling all possibilities of quoting when it is.
See, backslash is the standard path separator for Windows. It has been there for ages, and it's going to remain. It's not hard to handle it either, and if you want a premade portable solution to OS paths - just use boost::filesystem (or whatever the analog is for your language/framework). It's really not hard.MS is just being assholes about the C99 stuff. First of all they ignored the BSD strlcpy and strlcat, which are quite proper solutions.
Regarding C99, MS guys have said time and again that nobody (who pays money) really cares. C++ TR1 was more important than that, and they've implemented it now (minus the C99 bits). C++0x is going to be important, and they're working on it. But how many C99-only projects you know? Yeah, right...Also, what C99 has to do with strlcpy/strlcat? And, while we're at it, what standard do they belong to, and who else supports them?
. Their "standard" is strcpy_s which *throws an exception* when the buffer overflows. That is just ludricous, what it means is that programs will throw exceptions and cause a DOS rather than just truncating. Really what they are trying to do is force everybody to use Windows-specific calls. Adding underscores to a random set of C99 functions that are safe, especially snprintf, is the real giveaway that they just want to make it impossible to port code.
Just so you'd know, the *_s functions MS provides are not some completely proprietary extension. They're being standardized as TR 24731 "Extensions to the C Library Part I: Bounds-checking interfaces" to ISO C. It is developed as any proper ISO standard (and unlike OOXML). You can see the draft for yourself, as well as the rationale.Also note that these functions do not throw exceptions! They invoke a constraint violation handler which can be set via set_constraint_handler_s(). If you do not want your program to terminate, then you can write your own handler, and explicitly forbid termination from there - in that case, you'll get the typical truncating behavior. However, it has been long held that violating a contract should not go lightly - it is a bug, and trying to recover it (by e.g. truncating) merely sweeps it under the rug, quite likely resulting in a later failure, or, worse, silent incorrect behavior. Personally, I don't see any valid reason whatsoever to rely on truncation in strcpy - it's means you're silently accepting a data loss at some cutoff point. The proper way is to measure the length of the source string first, and allocate the buffer of the right size (possibly on stack with heap fallback above a certain size for performance).
The C people should realize that we want "N bits" and really don't give a damn about any other considerations
You can try to tell that to the guys at comp.std.c or comp.lang.c.moderated. We'll see how many of "we" actually want that sort of thing; so far, the vast majority finds stdint.h and typedefs more than adequate. If you really want 22-bit ints, you're always free to use bit fields. -
Re:Does Ballmer really want the answer
The Win32 api certainly does accept forward slashes just fine. The problem is appliations and clueless programmers that don't think files ever contain forward slashes. Generally you cannot cut & paste or drag & drop or type in a filename with forward slashes into many applications, and operation system calls like getcwd cannot return strings with forward slashes without them crashing. What I want Microsoft to do is insist that the programs should all accept and work with these, or they don't get the "windows certified" label or something. I am really sick and tired of having to add tons of code to decide whether a piece of text is a filename or not and disabling all possibilities of quoting when it is.
See, backslash is the standard path separator for Windows. It has been there for ages, and it's going to remain. It's not hard to handle it either, and if you want a premade portable solution to OS paths - just use boost::filesystem (or whatever the analog is for your language/framework). It's really not hard.MS is just being assholes about the C99 stuff. First of all they ignored the BSD strlcpy and strlcat, which are quite proper solutions.
Regarding C99, MS guys have said time and again that nobody (who pays money) really cares. C++ TR1 was more important than that, and they've implemented it now (minus the C99 bits). C++0x is going to be important, and they're working on it. But how many C99-only projects you know? Yeah, right...Also, what C99 has to do with strlcpy/strlcat? And, while we're at it, what standard do they belong to, and who else supports them?
. Their "standard" is strcpy_s which *throws an exception* when the buffer overflows. That is just ludricous, what it means is that programs will throw exceptions and cause a DOS rather than just truncating. Really what they are trying to do is force everybody to use Windows-specific calls. Adding underscores to a random set of C99 functions that are safe, especially snprintf, is the real giveaway that they just want to make it impossible to port code.
Just so you'd know, the *_s functions MS provides are not some completely proprietary extension. They're being standardized as TR 24731 "Extensions to the C Library Part I: Bounds-checking interfaces" to ISO C. It is developed as any proper ISO standard (and unlike OOXML). You can see the draft for yourself, as well as the rationale.Also note that these functions do not throw exceptions! They invoke a constraint violation handler which can be set via set_constraint_handler_s(). If you do not want your program to terminate, then you can write your own handler, and explicitly forbid termination from there - in that case, you'll get the typical truncating behavior. However, it has been long held that violating a contract should not go lightly - it is a bug, and trying to recover it (by e.g. truncating) merely sweeps it under the rug, quite likely resulting in a later failure, or, worse, silent incorrect behavior. Personally, I don't see any valid reason whatsoever to rely on truncation in strcpy - it's means you're silently accepting a data loss at some cutoff point. The proper way is to measure the length of the source string first, and allocate the buffer of the right size (possibly on stack with heap fallback above a certain size for performance).
The C people should realize that we want "N bits" and really don't give a damn about any other considerations
You can try to tell that to the guys at comp.std.c or comp.lang.c.moderated. We'll see how many of "we" actually want that sort of thing; so far, the vast majority finds stdint.h and typedefs more than adequate. If you really want 22-bit ints, you're always free to use bit fields. -
Re:Trolls are great :)
-
Re:Strostrup is the problem
Their latest monstrosity is move semantics, i.e. data allocated on the heap are moved around and freed by the last object that has their ownership. Move semantics work just like auto_ptr, i.e. a newly constructed object gets the ownership of the data...this guarantees disaster, because in a complex expression/statement block you will not be able to tell which destructor really destroyed the data...
You are misinformed.
Move semantics are enabled by rvalue references (i.e., references that bind to rvalues, as opposed to the existing references in C++ '98 that bind to lvalues).
Rvalue references and move semantics solve a performance problem, not a memory management problem.
The typical use case is to have a constructor (called the "move constructor", which is like a copy ctor but takes rvalues instead of lvalues) bind to the temporary class objects that are often created in a complex expression. By pilfering the resources of an object that's guaranteed to exist only until the end of the full-expression in which it's created, you can avoid successive calls to expensive allocators of resources (like heap memory).
If you want to understand this, read The Fine Paper. Note especially the std::string example. (This is an early version of the proposal; subsequent versions polished the proposed wording changes to the actual normative wording of the C++0X Working Draft.)And all this because they deny to fix the language and put garbage collection in!
You are appallingly misinformed.
First, note that you do not get move semantics without rvalue references. And move semantics are meant to apply only to rvalues (not lvalues -- although you can explicitly force an lvalue-to-rvalue conversion and then do a move, but generally there is no need to).
Second, the performance gained from compiling existing C++ programs against rvalue-ref-enabled libraries is quite measurable, and in many cases the speed gains are close to a factor of ten over the version of the same library without move semantics.
Third, when the committee accepted the proposal for rvalue references, *nobody* claimed that it would be used as a substitute for garbage collection. They are totally separate things that solve different problems. If and when Garbage Collection is accepted, you can look forward to programs that use *both* rvalue references *and* GC (and with good reasons for using both). On the other hand, if GC ultimately does not make it into C++0x, you should be aware that
(a) it will not have been the fault of proponents of ravlue references (who are also mostly proponents of GC) and
(b) work toward GC will continue so that it can be adopted into the following C++ (probably C++13).
I have a fourth point, but first:with GC, move semantics would not be required, as the shared data structures would be deleted only when not referenced by any code. And their excuse for not putting garbage collection in C++ is just as lame: "some people will react against it!" even if GC is totally optional!!!
Fourth: the committee has not rejected garbage collection.
Programmer-controlled GC (i.e., GC that can be explicitly disabled or explicitly enabled) is being worked on by some smart people whose names you should recognize if you really care about this stuff, and the chances of it being accepted are looking good. It's taking longer to put in than rvalue references because it's considerably more complicated than rvalue references.
There is so much more written in this thread that should be publicly corrected. Suffice to say, if you really want to know what's true about the developments of C++0x, you should honestly read about some of the topics. And if you think Stroustru -
Re:Strostrup is the problem
Their latest monstrosity is move semantics, i.e. data allocated on the heap are moved around and freed by the last object that has their ownership. Move semantics work just like auto_ptr, i.e. a newly constructed object gets the ownership of the data...this guarantees disaster, because in a complex expression/statement block you will not be able to tell which destructor really destroyed the data...
You are misinformed.
Move semantics are enabled by rvalue references (i.e., references that bind to rvalues, as opposed to the existing references in C++ '98 that bind to lvalues).
Rvalue references and move semantics solve a performance problem, not a memory management problem.
The typical use case is to have a constructor (called the "move constructor", which is like a copy ctor but takes rvalues instead of lvalues) bind to the temporary class objects that are often created in a complex expression. By pilfering the resources of an object that's guaranteed to exist only until the end of the full-expression in which it's created, you can avoid successive calls to expensive allocators of resources (like heap memory).
If you want to understand this, read The Fine Paper. Note especially the std::string example. (This is an early version of the proposal; subsequent versions polished the proposed wording changes to the actual normative wording of the C++0X Working Draft.)And all this because they deny to fix the language and put garbage collection in!
You are appallingly misinformed.
First, note that you do not get move semantics without rvalue references. And move semantics are meant to apply only to rvalues (not lvalues -- although you can explicitly force an lvalue-to-rvalue conversion and then do a move, but generally there is no need to).
Second, the performance gained from compiling existing C++ programs against rvalue-ref-enabled libraries is quite measurable, and in many cases the speed gains are close to a factor of ten over the version of the same library without move semantics.
Third, when the committee accepted the proposal for rvalue references, *nobody* claimed that it would be used as a substitute for garbage collection. They are totally separate things that solve different problems. If and when Garbage Collection is accepted, you can look forward to programs that use *both* rvalue references *and* GC (and with good reasons for using both). On the other hand, if GC ultimately does not make it into C++0x, you should be aware that
(a) it will not have been the fault of proponents of ravlue references (who are also mostly proponents of GC) and
(b) work toward GC will continue so that it can be adopted into the following C++ (probably C++13).
I have a fourth point, but first:with GC, move semantics would not be required, as the shared data structures would be deleted only when not referenced by any code. And their excuse for not putting garbage collection in C++ is just as lame: "some people will react against it!" even if GC is totally optional!!!
Fourth: the committee has not rejected garbage collection.
Programmer-controlled GC (i.e., GC that can be explicitly disabled or explicitly enabled) is being worked on by some smart people whose names you should recognize if you really care about this stuff, and the chances of it being accepted are looking good. It's taking longer to put in than rvalue references because it's considerably more complicated than rvalue references.
There is so much more written in this thread that should be publicly corrected. Suffice to say, if you really want to know what's true about the developments of C++0x, you should honestly read about some of the topics. And if you think Stroustru -
Re:Maybe the real problem...
The thing is, C++ is huge. Just to have a solid working knowledge of the core language, you need to master whole rafts of things that have nothing whatsoever to do with the low-level operation of the machine, because even the core is a labyrinth of obscure corner cases that make language lawyers drool, and which, if expressed in pseudo-code, would be a bunch of gigantic switch statements with a couple dozen levels of ifs nested inside each case.
Absolutely. This is fairly easy to check, too; here's the most recent draft for C++0x, and it's already 1200+ pages! And they haven't even included everything they want to get there yet (such as concepts, which alone will add a lot more; a full list of what's not yet there, but is going to be, can be seen here). Now, how do you think, how many developers are going to understand it well enough? -
Re:Maybe the real problem...
The thing is, C++ is huge. Just to have a solid working knowledge of the core language, you need to master whole rafts of things that have nothing whatsoever to do with the low-level operation of the machine, because even the core is a labyrinth of obscure corner cases that make language lawyers drool, and which, if expressed in pseudo-code, would be a bunch of gigantic switch statements with a couple dozen levels of ifs nested inside each case.
Absolutely. This is fairly easy to check, too; here's the most recent draft for C++0x, and it's already 1200+ pages! And they haven't even included everything they want to get there yet (such as concepts, which alone will add a lot more; a full list of what's not yet there, but is going to be, can be seen here). Now, how do you think, how many developers are going to understand it well enough? -
Re:It's true enough about LinuxAnd APIs. I mean, by now, transactions on a filesystem should be part of your standard C-API; read, write, oh sorry, I didn't mean that: rollback. Why isn't it ? I think you need to take another look at the standard C API. And just so you know, the "STANDARD C API" is not a "Unix" thing. Perhaps you should look at http://www.open-std.org/jtc1/sc22/wg14/