Posts: 135 / Nickname: fsommers / Registered: January 19, 2002 7:24 AM
Safe Labels in C++
October 1, 2007 1:00 PM
|
This article presents a solution to the problem of constraining bit
operations to allow only safe and legitimate ones, and turn all invalid bit manipulations into compile-time errors. http://www.artima.com/cppsource/safelabels.html What do you think of the type-safe bit manipulations described in this article? |
Posts: 2 / Nickname: iplayfast / Registered: October 2, 2007 0:03 AM
Re: Safe Labels in C++
October 2, 2007 5:15 AM
|
It seems to me that you are making a 200 line program to do the equivalent to a 20 line program. This all compiles down to the 20 line program in the end since it's all macro manipulations, but I keep thinking there must be a better way.
Off the top of my head... class Cat { const unsigned int CAT_SLEEPING = 0x0001; const unsigned int CAT_PURRING = 0x0002; const unsigned int CAT_PLAYING = 0x0004; unsigned int state; public: Cat() { state =0; } void SetPurring() { state |= CAT_PURRING; } void ResetPurring() { state &= ~CAT_PURRING; } bool GetPurring() { return state & CAT_PURRING; } void SetSleeping() { state |= CAT_SLEEPING; } void ResetSleeping() { state &= ~CAT_SLEEPING; } bol GetSleeping() { return state & CAT_SLEEPING; } and so on. }; It's used like: Cat c; c.SetPurring(); ... if (c.GetPurring() || c.GetSleeping()) ... To me this is much simpler to read, cannot be messed up or mixed between functions and each class is self contained (which is what you want with object oriented software). |
Posts: 2 / Nickname: iplayfast / Registered: October 2, 2007 0:03 AM
Re: Safe Labels in C++
October 2, 2007 5:16 AM
|
I forgot to mention, if those functions are made inline, then it compiles down to the same type of bit manipulations that would have been in the original program as well.
|
Posts: 1 / Nickname: pikus / Registered: October 2, 2007 3:22 AM
Re: Safe Labels in C++
October 2, 2007 8:27 AM
|
First of all, the assumption is that there is a lot more client code than there are declarations, so the template bit field and the macro declarations are irrelevant as far as the size is concerned. If you start with a 20-line program in the first place, then you can replace all bit manipulation operations with member function calls. How would you like to do the same in 2 million line program?
|
Posts: 1 / Nickname: cm / Registered: April 21, 2003 6:06 AM
Re: Safe Labels in C++
October 1, 2007 4:09 PM
|
"C++ is a language for writing efficient high-performance programs"
That's funny! I, like others who have been around long enough to remember the early language wars, find this seriously amusing. Not because it's wrong, per se, but because of the change in perceptions the years have wrought. In ten years: "Python/Ruby/Perl/PHP is a language for writing efficient high-performance programs" In twenty years: "Javascript is a language for writing efficient high-performance programs" |
Posts: 2 / Nickname: aleksf / Registered: August 16, 2006 5:02 AM
Re: Safe Labels in C++
October 2, 2007 5:52 AM
|
> I, like others who have been around long enough to
> remember the early language wars, find this seriously > amusing. Not because it's wrong, per se, but because of > the change in perceptions the years have wrought. Read, sort and write floating point numbers C/C++ ratio (optimized) 500,000 el. 2.04 5,000,000 el. 4.62 For more details, see: http://www.research.att.com/~bs/new_learning.pdf Not to start a 'language war', but why don't you back up your 'per se' claim with some hard data? |
Posts: 13 / Nickname: schluehk / Registered: January 20, 2005 5:46 AM
Re: Safe Labels in C++
October 1, 2007 6:35 PM
|
> "C++ is a language for writing efficient high-performance
> programs" > > That's funny! > > I, like others who have been around long enough to > remember the early language wars, find this seriously > amusing. Not because it's wrong, per se, but because of > the change in perceptions the years have wrought. Indeed. C++ wasn't considered as such in its early days. There were Fortran and C with better predictability of performance and memory. C++ was just an application programming language, not scaring away those who didn't want to program OO but procedural C code instead. This changed in the 90s. Most notably with WinNT being written in C++. > In ten years: > > "Python/Ruby/Perl/PHP is a language for writing efficient > high-performance programs" Maybe not. But one of them will be the prefered choice in writing "large scale business applications" and evil minded persons will say "Ruby is the new COBOL" since one language always has to be COBOL no matter which. > > In twenty years: > > "Javascript is a language for writing efficient > high-performance programs" JavaScript will be the language for writing "net-centric operating systems". So definitely yes: JavaScript will become the most widely used systems programming language. |
Posts: 98 / Nickname: achilleas / Registered: February 3, 2005 2:57 AM
Re: Safe Labels in C++
October 2, 2007 2:46 AM
|
> changed in the 90s. Most notably with WinNT being written
> in C++. Is NT really written in C++? All the APIs Microsoft exposes are in C. Getting back to the original topic, it's very easy to make typesafe values in C++ by making them classes. For example:
etc So it's not that difficult to make constant bitfields, which is certainly a good practice. |
Posts: 13 / Nickname: schluehk / Registered: January 20, 2005 5:46 AM
Re: Safe Labels in C++
October 2, 2007 5:59 AM
|
> > changed in the 90s. Most notably with WinNT being
> written > > in C++. > > Is NT really written in C++? All the APIs Microsoft > exposes are in C. It's a bit hard to find a reference. AFAIK Windows NT started in the early '90s as an OS project implemented in pure C and was released as Windows NT 3.1. The implementation language gradually shifted towards C++ in Windows NT 4.0 and was almost entirely C++ with Windows NT 5.0 aka Win2K. |
Posts: 98 / Nickname: achilleas / Registered: February 3, 2005 2:57 AM
Re: Safe Labels in C++
October 3, 2007 1:35 AM
|
> It's a bit hard to find a reference. AFAIK Windows NT
> started in the early '90s as an OS project implemented in > pure C and was released as Windows NT 3.1. The > implementation language gradually shifted towards C++ in > Windows NT 4.0 and was almost entirely C++ with Windows NT > 5.0 aka Win2K. Do you have any references about that? I say that NT from Win2K to Vista are still written in C. |
Posts: 62 / Nickname: zbo / Registered: January 20, 2007 9:22 AM
Re: Safe Labels in C++
October 4, 2007 4:09 AM
|
There's a couple of interesting lessons here.
First, the use of 0x0001 is silly. It compiles down to the same thing as 1<<0, making the code pattern become: 1<<0 1<<1 1<<2 etc... The meaning is much clearer, and it is easier to type. It's also an incredibly useful code generation pattern. Second, size_t might be a better type choice than int for these bit fields. Third, I think the article could have had a better pedagogical approach by asking, "Is it clear, concise? Is it efficient? Is it type-safe? Is it length-safe? Is it usable in a template?" for each example given. These are the big questions. Always try to answer the big questions directly. Fourth, we should be programming in Digital Mars D :) |
Posts: 1 / Nickname: buyvicodin / Registered: October 4, 2007 10:24 PM
Re: Safe Labels in C++
October 5, 2007 3:29 AM
|
0000
|
Posts: 40 / Nickname: ntrif / Registered: June 30, 2004 1:10 AM
Re: Safe Labels in C++
October 2, 2007 6:15 AM
|
The important (off-topic) things first :)
1) C++ compilers have improved a lot in the last 10 years, and there is no reason for a C++ program to be less efficient than an equivalent C one. Of course, Fortran is still the "daddy" when it comes to performance (at least numeric calculations). 2) NT kernel is pure C, but pretty much everything else in Windows is C++ these days. Now to the less important stuff (the article :) ) It is a really interesting approach to solve a real problem: bit-mangling is something that is way too easy to screw up. I wonder, however if there is an approach with (template?) inline functions rather than macros. |
Posts: 98 / Nickname: achilleas / Registered: February 3, 2005 2:57 AM
Re: Safe Labels in C++
October 3, 2007 1:38 AM
|
> The important (off-topic) things first :)
> > 1) C++ compilers have improved a lot in the last 10 years, > and there is no reason for a C++ program to be less > efficient than an equivalent C one. Of course, Fortran is > still the "daddy" when it comes to performance (at least > numeric calculations). When was a C++ program slower than the equivalent C program? I don't think there was ever such a case. C++ was deemed slower than C in the same tasks that C did, but in an object-oriented way. But the programs were not equivalent. Fortran is the king of numeric computation performance because it does not have aliases which prevent a compiler to do the appropriate optimizations. > > 2) NT kernel is pure C, but pretty much everything else in > Windows is C++ these days. > I think the definition of the O/S is not the applications distributed with it but its kernel and drivers. And I think all of NT is written in C, even in these days. |
Posts: 40 / Nickname: ntrif / Registered: June 30, 2004 1:10 AM
Re: Safe Labels in C++
October 3, 2007 6:18 AM
|
> When was a C++ program slower than the equivalent C
> program? I don't think there was ever such a case. It definitelly was, at least with some compilers. For instance, read some discussions on rewriting Linux kernel in C++ (not that L. Torvalds knows anything about C++, but he complained that even the C code compiled with g++ was slower): http://www.kernel.org/pub/linux/docs/lkml/#s15-3 > I think the definition of the O/S is not the applications > distributed with it but its kernel and drivers. And I > think all of NT is written in C, even in these days. Most definitions of "Operating System" include kernel + various user-space systems (think "GNU/Linux"). NT kernel is written with C, but everything else (shell, DirectX, COM, ...) is C++. |
Posts: 98 / Nickname: achilleas / Registered: February 3, 2005 2:57 AM
Re: Safe Labels in C++
October 4, 2007 1:44 AM
|
> > When was a C++ program slower than the equivalent C
> > program? I don't think there was ever such a case. > > It definitelly was, at least with some compilers. For > instance, read some discussions on rewriting Linux kernel > in C++ (not that L. Torvalds knows anything about C++, but > he complained that even the C code compiled with g++ was > slower): http://www.kernel.org/pub/linux/docs/lkml/#s15-3 It does not say anything, really, just a vague reference to gcc being slower in C++ than in C. Which says nothing. And it does not talk about 'equivalent programs'. > > > > I think the definition of the O/S is not the > applications > > distributed with it but its kernel and drivers. And I > > think all of NT is written in C, even in these days. > > Most definitions of "Operating System" include kernel + > various user-space systems (think "GNU/Linux"). NT kernel > is written with C, but everything else (shell, DirectX, > COM, ...) is C++. All these are programs on top of the kernel, so they are not part of the O/S, they are part of the O/S distribution. There is a difference. |
Posts: 40 / Nickname: ntrif / Registered: June 30, 2004 1:10 AM
Re: Safe Labels in C++
October 4, 2007 4:15 AM
|
> It does not say anything, really, just a vague reference
> to gcc being slower in C++ than in C. Which says nothing. > And it does not talk about 'equivalent programs'. "It turned out that compiling a piece of C code with g++ would give you worse code. It shouldn't have made a difference, but it did." > All these are programs on top of the kernel, so they are > not part of the O/S, they are part of the O/S > distribution. There is a difference. :) O/S != kernel; O/S = kernel + shell + various_other_user_space_services; } |
Posts: 98 / Nickname: achilleas / Registered: February 3, 2005 2:57 AM
Re: Safe Labels in C++
October 5, 2007 5:13 AM
|
> > It does not say anything, really, just a vague
> reference > > to gcc being slower in C++ than in C. Which says > nothing. > > And it does not talk about 'equivalent programs'. > > "It turned out that compiling a piece of C code with g++ > would give you worse code. It shouldn't have made a > difference, but it did." I never believed that. They never showed any code. > > > All these are programs on top of the kernel, so they > are > > not part of the O/S, they are part of the O/S > > distribution. There is a difference. > > :) > > O/S != kernel; > O/S = kernel + shell + various_other_user_space_services; > } In the context of programming languages, the only part of an O/S distribution that count as an O/S is the kernel. You can't say, for example, that Internet Explorer is part of the O/S, because it is a normal application that could have been written in any language. |
Posts: 18 / Nickname: mlybbert / Registered: April 27, 2005 11:51 AM
Why not C bitfields?
October 10, 2007 1:56 PM
|
I had a hard time reading the article, because I felt that it solves an artificial problem. I can't see why a C bitfield ( http://msdn2.microsoft.com/en-us/library/yszfawxh.aspx for instance) wouldn't solve the problem:
struct Cat_state |
Posts: 1 / Nickname: mtadeunet / Registered: November 12, 2007 2:10 AM
Re: Why not C bitfields?
November 12, 2007 10:36 AM
|
I read a book that noted just that(can remember which), but I picked the example described there and added a few features:
// from the book template<unsigned long N> struct binary { static const unsigned int digit = N % 10; BOOST_STATIC_ASSERT(digit == 0 || digit == 1); static unsigned long const value = binary<N/10>::value * 2 + digit; }; template<> struct binary<0> { static unsigned int const value = 0; }; // from me... template<unsigned long N, unsigned long S> struct binary_shift_left : binary<N> { static unsigned long const value = (binary<N>::value << S); }; template<unsigned long N, unsigned long S> struct binary_shift_right : binary<N> { static unsigned long const value = (binary<N>::value >> S); }; template<unsigned long N, unsigned long P = 0> struct flag : binary_shift_left<N, P> { }; template<unsigned long P> struct bit_flag : flag<1, P>{ }; // usage int main(int argc, char *argv[]) { unsigned long flags = 0x00; flags = binary<1010101010>::value; flags |= bit_flag< 1 >::value; flags |= bit_flag< 2 >::value; flags |= bit_flag< 3 >::value; flags |= bit_flag< 4 >::value; flags |= bit_flag< 5 >::value; flags |= bit_flag< 6 >::value; flags |= bit_flag< 7 >::value; flags |= bit_flag< 8 >::value; flags |= flag<11, 9>::value | flag<101, 5>::value; cout << binary<1111>::value << endl; return EXIT_SUCCESS; } It's to be noticed that recent compilers will resolve the templates and the code remains as optimized as in C. |
Posts: 1 / Nickname: ma740988 / Registered: December 27, 2008 5:02 PM
Re: Safe Labels in C++
December 27, 2008 11:12 PM
|
Interesting to say the least. I'll need to read the article again but assume CAT_PURRING required 4 bits. To provide coverage across a range, I would end up with:
BIT_CONST( Cat_state, CAT_SLEEPING, 1 ); BIT_CONST( Cat_state, CAT_PURRING, 2 ); BIT_CONST( Cat_state, CAT_PLAYING, 6 ); i.e CAT_PLAYING will start at location 6? |