**** REPOST with BROKETS RESTORED **** Dang it, plain old text is not so plain after all.
That's a good explanation of what happened.
The analysis of the predicament that vector<bool> creates is a deeper matter.
It's the STL algorithms that enforce the requirement that &*iter always be a valid expression. What this means is that the STL algorithms are not officially capable of working with proxy iterators, unless the proxy iterators are iterating over a manifest representation.
People apply STL algorithms to proxy iterators all the time and get away with it because very few algorithms actually take the element address which they are entitled to take.
Properly speaking, the STL algorithms should be referred to as the STL container algorithms, because they promise to work when given iterators with container semantics (that every element has an address in memory).
This makes the STL algorithms far less generic than they pretend to be. vector<bool> ends up taking the flak for pointing out a defect in the genericity of the STL algorithms. The failed experiment ended up in the C++ standard because too many people involved presumed that the STL algorithms promised a higher degree of genericity than the standard officially permits.
A principled solution to this problem would be to extend iterator traits to allow algorithms to determine whether reference semantics exist for the iterators supplied and act appropriately. This would greatly increase the formal genericity of the STL algorithms.
One could also define an element adaptor such as this:
vector<unreferenced<bool> > V;
and specializations for the containers such that:
template <template Contain, class T> Contain<unreferenced<T> >
provides a container interface with no reference semantics.
OK that's mostly a joke.
There are many classes that people might wish to implement thinking they are container classes, but which are unable to provide reference semantics.
I tend to think of containers with reference semantics as strong containers and synthetic containers lacking reference semantics as weak containers. Weak containers should be able to supply iterators to the vast majority of algorithms.
The problem with the vector<bool> specialization as defined is that it specializes a strong container into a weak container. This is definitely wrong. But not nearly as wrong as the presumption made in the algorithms that all iterators supplied have strong container semantics.
The analysis of the predicament that vector creates is a deeper matter.
It's the STL algorithms that enforce the requirement that &*iter always be a valid expression. What this means is that the STL algorithms are not officially capable of working with proxy iterators, unless the proxy iterators are iterating over a manifest representation.
People apply STL algorithms to proxy iterators all the time and get away with it because very few algorithms actually take the element address which they are entitled to take.
Properly speaking, the STL algorithms should be referred to as the STL container algorithms, because they promise to work when given iterators with container semantics (that every element has an address in memory).
This makes the STL algorithms far less generic than they pretend to be. vector ends up taking the flak for pointing out a defect in the genericity of the STL algorithms. The failed experiment ended up in the C++ standard because too many people involved presumed that the STL algorithms promised a higher degree of genericity than the standard officially permits.
A principled solution to this problem would be to extend iterator traits to allow algorithms to determine whether reference semantics exist for the iterators supplied and act appropriately. This would greatly increase the formal genericity of the STL algorithms.
One could also define an element adaptor such as this:
vector > V;
and specializations for the containers such that:
template
Contain >
provides a container interface with no reference semantics.
OK that's mostly a joke.
There are many classes that people might wish to implement thinking they are container classes, but which are unable to provide reference semantics.
I tend to think of containers with reference semantics as strong containers and synthetic containers lacking reference semantics as weak containers. Weak containers should be able to supply iterators to the vast majority of algorithms.
The problem with the vector specialization as defined is that it specializes a strong container into a weak container. This is definitely wrong. But not nearly as wrong as the presumption made in the algorithms that all iterators supplied have strong container semantics.
] There being very few programmers quite experienced in both...
That's a huge laugh. I can tell you hang with an under 30 crowd. In my generation (we're not all extinct yet) there are few hardcore C++ programmers who weren't once upon a time masterful C programmers. And it's not like we forget, either. Unfortunately, we're constantly reminded of all the defects of C because C++ leverages so many of them.
There are many excellent system programmers out there who work almost exclusively in C (I'd include the Perl internals as system programming).
There are far fewer excellent application domain programmers who prefer C as their primary language. Those who wanted sharper knives went to C++; those who wanted more conformity went to Java; those who wanted to retire a few years early returned to COBOL.
This thread started off with a request for a real example of a case where C++ outperforms C. qsort is such a case. No one is saying that the efficiency of sort in C++ is the fundamental reason we chose to program in C++
I chose to program in C++ because retains its efficiency at high levels of compositionality. This allows me to use more powerful abstractions without worrying that speed will become a serious problem.
I can think of two cases which C++ wins out of hand right off the top of my head.
qsort() versus sort
sort wins hands down. sort inlines the comparison primitive. qsort must call the comparison routine via a function pointer.
This has been documented many times with actual numbers.
The second case is an efficient implementation of accumulate for floating point operands. If your machine has a multicycle latency for the result of a floating point addition (3 or 4 cycles is typical) you can compute the sequence sum faster by using three or four intermediate sums (adding a different term to a different intermediate on every cycle, then summing the intermediate values to get the final result).
A hand coded loop in C with a single summand won't perform as well.
You might think you are doing yourself a favor, but you aren't. The other response explains some of the reasons. There are more. Many many more.
One of the areas where the C++ language could be improved is allowing classes to declare the formal requirements on any derivation from that class so that incorrect (unsafe) derivations were difficult to pull off.
Just because something is a class, and C++ allows almost any class to be inherited, that doesn't mean you should go ahead and stick it in your ear.
A more viable route to the same end is to write a template adaptor class. Unfortunately, you'll learn more from trying to do this than you are prepared to cope with.
Short cut: the longest distance between two points.
RTTI was intended for no such purpose. 99 times out of 100 the use of RTTI is a red flag for a serious design flaw.
I've been using STL since nearly the day HP released the first reference implementation and I can't think of a single occasion where I've used RTTI except to break a compiler just for fun.
You've completely confused the notions of genericity with polymorphism. generic programming is sometimes defined as static polymorphism: polymorphism which resolves ***at compile time***.
]] The point is that ten years ago C++ was hyped to the same extent...
error: inference via hype; hype is nilpotent
To dredge up a really old term: garbage in, garbage out.
Ten years ago OO langauges in general were strongly hyped. The generic side of C++ evolved out of a growing recognition that there was another component of programming orthogonal to OOP. Many people regard the last ten years of C++'s evolution as the most compelling part.
Any point which takes as its premise what the marketrons were saying is no point at all.
Binary incompatibility is a well known and well documented problem. Given your attitude, you will be better served by a language which specializes in late bindings. Late binding is the patron saint for wading into something without first scouting the terrain.
There is now a standard ABI for C++, but it is not yet widely supported. Too many vendors don't regard this as a priority.
The reason that gcc 3 failed is that it is attempting to support the standard ABI. gcc 3 had to change in order to do so.
I'm sure you'll be happy to know that in the case of gcc it was the cure that killed you. OTOH, avoiding VC6 like the plague is not such a bad idea.
In the simplest examples, the cost of automatic bounds checking is not terribly onerous. It's somewhat more painful on architectures with small register files (e.g. x86).
The problems with automatic bounds checking snowball when you write template code that expands through many layers. There are reasons why compilers can't always eliminate operations at the bottom of these compositions.
What you end up destroying is compositionality. Rather than mandate checks at the lowest layer of the composition, it's much better for highly abstract code to enforce the correct preconditions at the top of the abstraction tower.
If bounds checking has the end result of making good abstractions less viable, we can do without the bounds checking altogether.
The vast majority of the STL algorithms have a natural, efficient expression. I've read as least three different STL algorithm library sources and I didn't find much exceptional in how any of them implemented the basic algorithms.
The most complicated algorithms I can think of right now are the various sorting algorithms. The original HP implementation did a pretty reasonable job in making good use of the heap primitive. In order to implement these algorithms badly you'd need to completely ignore the model implementations.
The containers and the string class are a different matter. I can imagine slow implementations of map and string. In the case of string, it's almost impossible to implement it to be efficient for all cases. But don't blame the algorithms. They are at least as reliable as qsort() or rand() from the C library.
Once upon a time I had a version of Watcom which failed to implement the tail recursion properly and consumed linear stack space. It was widely documented that this is a required practice, but the Watcom programmer didn't bother to consult any precedents. If anything, these problems are less likely to occur in quality STL implementations.
I see no reason why the C++ standard should impose policies, such as error checking, on STL library developers, who have an extremely wide range of interests to serve.
If you want default error checking, obtain an STL implementation that performs default error checking. You don't understand my problems. I don't want your defaults.
My understanding of the history of the STL is that many of the committee members who voted in favor of the STL were extremely impressed by what the generic approach promised.
I agree that the STL containers are not particularly well suited as interface arguments. I find that I rarely do this. Either I create a template algorithm that takes generic iterators, or I pass application class objects directly.
What you have failed to understand is that C++ was designed to serve many different masters. Much of the shape of the STL was chosen to make it possible to build efficient 3rd party libraries on top of the STL algorithms.
These libraries might very well be performing their own error checking at a higher semantic layer. Layers upon layers of error checking finally lead to a completely safe library than no one can afford to use in a production system.
The type inference mechanisms in C++ have the full expressive power of a functional language. Type inference in C++ _is_ a functional language (type results are never changed once they are created).
The problem with C++ is not lack of expressive power, but that the expressive power is often difficult to leverage out in its purest form.
A polynomial time map implementation does not conform to the STL standard which makes execution order guarantees.
You presented your issue badly. You should have complained about a violation of the STL execution order requirements until they sent you something non-polynomial.
Chances are they would have solved the problem by improving their algorithm rather than making the insertion of the first element a ten second operation.
The extra burden on the compiler is there for the benefit of the programmer.
Compilers usually lag behind trends in how typical applications are written. It's much easier to improve a compiler when you have a representative code base against which to vet your changes.
All of the problems I'm aware of have good solutions in principle.
2. difficult to derive from STL classes
The STL classes weren't designed to support derivation. The STL is designed so that you can write your own container classes (or class hierarchies) in such a way that they remain compatible with the STL algorithms. The algorithms are the design center of the STL.
I think small_dick must have done a lot of self moderation to warrant a 5 for that wad of premajaculate.
90% of the ugliness in C++ is due to maintaining downward compatibility with C. That was a strategic decision from the outset, without which C++ most likely would never have become the subject of this thread.
Beyond those defects, it really comes down to whether a programmer is patient enough to cope with static binding and dynamic binding in the same context. Tell me what Java has accomplished when Java has the same expressive power for static bindings.
The generic idioms and implementation blocks are so different from conventional OO structure that you naturally find yourself acquiring different stylistic preferences.
Generic code is largely based on manipulations of types rather than values. Entirely different classes of mistakes are made manipulating types rather than values.
My guess is that the people on your team who were most sensitive to layout issues where the members of the team who were most clued into the fundamentally different expressive nature of generic code.
>> First off, the OTP is completely 100% unbreakable [in theory]. Even with infinite time an OTP is unbreakable.
> Wrong. Given infinite time, a monkey will eventually bang out the contents of the OTP. Nothing is unbreakable given infinite time. Period.
I hope this response will remove the impressive sentence "Period." from your vocabulary for a long, long time. Or maybe it means what it appears to mean: I'm so sure of myself I don't need to think.
The deal with OTP is that the number of possible keys is exactly equal to the number of possible messages. If you try all the keys, you get every possible message. It doesn't matter which message you start with. If you try all the keys you get all the possible messages. Is that progress?
In fact, with OTP the set of all keys is identical to the set of all messages (for a given bit length). By your definition of "break" you don't actually need to capture the encrypted message. The decrypted message is already in your keys file!
There is no way to know when a key you tried produced the correct output. Every output is produced by some key. Every output that is even vaguely plausible is in there. Every output entirely is in there somewhere.
With a roomful of monkeys I can break every message ever written. With an infinite amount of time they'll type out everything ever encrypted. I don't even need the original messages. Cool.
You should write a book: interception made easy. Or maybe you should just dig it out of your keys file. It'll save you the effort of putting your own words together in sensible patterns.
Re:In place swap of two variables
on
Deep Algorithms?
·
· Score: 1
The xor swap only makes sense if you use it to swap a bit field within the integral value.
Off the tip of my fingers I think it goes like this:
b ^= a; a ^= (b & bitmask); b ^= a;
Yes, that should be right since if the second statement is rendered idempotent by a zero bit in the bitmask it boils down to this:
b ^= a; b ^= a;
And we are back to the beginning again.
There's no good reason a compiler couldn't be coded to recognize this sequence of steps and apply instruction level optimizations, such as on x86 if your constant bitmask is just swapping the low byte. The single byte swap instruction could be substituted mechanically.
The program code:
uint32 a, b; b ^= a; a ^= (b & 0xFF); b ^= a;
Would be generated by the compiler as:
swap al, bl
Of course I'm joking that anyone would implement this optimization in a real compiler. But then take a look at recent developments to automate the generation of SIMD instructions for conventionally coded loops.
I think the boundary between what helps and what hinders the compiler is becoming extremely blurry.
Re:In place swap of two variables
on
Deep Algorithms?
·
· Score: 1
The floating point unit doesn't have an xor capability in any modern chip I've seen, unless the IA-64 bit slicing facilities for floating point manipulation include this.
It wouldn't be very hard to write an include file that undefs all C++ keywords.
#ifdef private
#undef private
#endif
and so it goes
The war might escalate, but the pedants will still win.
**** REPOST with BROKETS RESTORED ****
Dang it, plain old text is not so plain after all.
That's a good explanation of what happened.
The analysis of the predicament that vector<bool> creates is a deeper matter.
It's the STL algorithms that enforce the requirement that &*iter always be a valid expression. What this means is that the STL algorithms are not officially capable of working with proxy iterators, unless the proxy iterators are iterating over a manifest representation.
People apply STL algorithms to proxy iterators all the time and get away with it because very few algorithms actually take the element address which they are entitled to take.
Properly speaking, the STL algorithms should be referred to as the STL container algorithms, because they promise to work when given iterators with container semantics (that every element has an address in memory).
This makes the STL algorithms far less generic than they pretend to be. vector<bool> ends up taking the flak for pointing out a defect in the genericity of the STL algorithms. The failed experiment ended up in the C++ standard because too many people involved presumed that the STL algorithms promised a higher degree of genericity than the standard officially permits.
A principled solution to this problem would be to extend iterator traits to allow algorithms to determine whether reference semantics exist for the iterators supplied and act appropriately. This would greatly increase the formal genericity of the STL algorithms.
One could also define an element adaptor such as this:
vector<unreferenced<bool> > V;
and specializations for the containers such that:
template <template Contain, class T>
Contain<unreferenced<T> >
provides a container interface with no reference semantics.
OK that's mostly a joke.
There are many classes that people might wish to implement thinking they are container classes, but which are unable to provide reference semantics.
I tend to think of containers with reference semantics as strong containers and synthetic containers lacking reference semantics as weak containers. Weak containers should be able to supply iterators to the vast majority of algorithms.
The problem with the vector<bool> specialization as defined is that it specializes a strong container into a weak container. This is definitely wrong. But not nearly as wrong as the presumption made in the algorithms that all iterators supplied have strong container semantics.
That's a good explanation of what happened.
The analysis of the predicament that vector creates is a deeper matter.
It's the STL algorithms that enforce the requirement that &*iter always be a valid expression. What this means is that the STL algorithms are not officially capable of working with proxy iterators, unless the proxy iterators are iterating over a manifest representation.
People apply STL algorithms to proxy iterators all the time and get away with it because very few algorithms actually take the element address which they are entitled to take.
Properly speaking, the STL algorithms should be referred to as the STL container algorithms, because they promise to work when given iterators with container semantics (that every element has an address in memory).
This makes the STL algorithms far less generic than they pretend to be. vector ends up taking the flak for pointing out a defect in the genericity of the STL algorithms. The failed experiment ended up in the C++ standard because too many people involved presumed that the STL algorithms promised a higher degree of genericity than the standard officially permits.
A principled solution to this problem would be to extend iterator traits to allow algorithms to determine whether reference semantics exist for the iterators supplied and act appropriately. This would greatly increase the formal genericity of the STL algorithms.
One could also define an element adaptor such as this:
vector > V;
and specializations for the containers such that:
template
Contain >
provides a container interface with no reference semantics.
OK that's mostly a joke.
There are many classes that people might wish to implement thinking they are container classes, but which are unable to provide reference semantics.
I tend to think of containers with reference semantics as strong containers and synthetic containers lacking reference semantics as weak containers. Weak containers should be able to supply iterators to the vast majority of algorithms.
The problem with the vector specialization as defined is that it specializes a strong container into a weak container. This is definitely wrong. But not nearly as wrong as the presumption made in the algorithms that all iterators supplied have strong container semantics.
] There being very few programmers quite experienced in both
That's a huge laugh. I can tell you hang with an under 30 crowd. In my generation (we're not all extinct yet) there are few hardcore C++ programmers who weren't once upon a time masterful C programmers. And it's not like we forget, either. Unfortunately, we're constantly reminded of all the defects of C because C++ leverages so many of them.
There are many excellent system programmers out there who work almost exclusively in C (I'd include the Perl internals as system programming).
There are far fewer excellent application domain programmers who prefer C as their primary language. Those who wanted sharper knives went to C++; those who wanted more conformity went to Java; those who wanted to retire a few years early returned to COBOL.
This thread started off with a request for a real example of a case where C++ outperforms C. qsort is such a case. No one is saying that the efficiency of sort in C++ is the fundamental reason we chose to program in C++
I chose to program in C++ because retains its efficiency at high levels of compositionality. This allows me to use more powerful abstractions without worrying that speed will become a serious problem.
I can think of two cases which C++ wins out of hand right off the top of my head.
qsort() versus sort
sort wins hands down. sort inlines the comparison primitive. qsort must call the comparison routine via a function pointer.
This has been documented many times with actual numbers.
The second case is an efficient implementation of accumulate for floating point operands. If your machine has a multicycle latency for the result of a floating point addition (3 or 4 cycles is typical) you can compute the sequence sum faster by using three or four intermediate sums (adding a different term to a different intermediate on every cycle, then summing the intermediate values to get the final result).
A hand coded loop in C with a single summand won't perform as well.
Was that the typical length of your problem report?
You might think you are doing yourself a favor, but you aren't. The other response explains some of the reasons. There are more. Many many more.
One of the areas where the C++ language could be improved is allowing classes to declare the formal requirements on any derivation from that class so that incorrect (unsafe) derivations were difficult to pull off.
Just because something is a class, and C++ allows almost any class to be inherited, that doesn't mean you should go ahead and stick it in your ear.
A more viable route to the same end is to write a template adaptor class. Unfortunately, you'll learn more from trying to do this than you are prepared to cope with.
Short cut: the longest distance between two points.
RTTI was intended for no such purpose. 99 times out of 100 the use of RTTI is a red flag for a serious design flaw.
I've been using STL since nearly the day HP released the first reference implementation and I can't think of a single occasion where I've used RTTI except to break a compiler just for fun.
You've completely confused the notions of genericity with polymorphism. generic programming is sometimes defined as static polymorphism: polymorphism which resolves ***at compile time***.
]] The point is that ten years ago C++ was hyped to the same extent
error: inference via hype; hype is nilpotent
To dredge up a really old term: garbage in, garbage out.
Ten years ago OO langauges in general were strongly hyped. The generic side of C++ evolved out of a growing recognition that there was another component of programming orthogonal to OOP. Many people regard the last ten years of C++'s evolution as the most compelling part.
Any point which takes as its premise what the marketrons were saying is no point at all.
Binary incompatibility is a well known and well documented problem. Given your attitude, you will be better served by a language which specializes in late bindings. Late binding is the patron saint for wading into something without first scouting the terrain.
There is now a standard ABI for C++, but it is not yet widely supported. Too many vendors don't regard this as a priority.
The reason that gcc 3 failed is that it is attempting to support the standard ABI. gcc 3 had to change in order to do so.
I'm sure you'll be happy to know that in the case of gcc it was the cure that killed you. OTOH, avoiding VC6 like the plague is not such a bad idea.
I have to repeat myself here.
Bounds checking is what you do once your high level engineering efforts have failed.
If catching bound exceptions is commonplace on your projects, either your programmers are poorly trained, or your design lacks sufficient abstraction.
I've worked on some very complicated C++ systems where bounds errors were at the bottom of the risk chart.
Vastly more serious and difficult problems are managing allocation lifetimes, thread safety, and exception safety.
Give up on automatic bounds checking. Throw me something that will solve a problem I don't already have under complete control to begin with.
In the simplest examples, the cost of automatic bounds checking is not terribly onerous. It's somewhat more painful on architectures with small register files (e.g. x86).
The problems with automatic bounds checking snowball when you write template code that expands through many layers. There are reasons why compilers can't always eliminate operations at the bottom of these compositions.
What you end up destroying is compositionality. Rather than mandate checks at the lowest layer of the composition, it's much better for highly abstract code to enforce the correct preconditions at the top of the abstraction tower.
If bounds checking has the end result of making good abstractions less viable, we can do without the bounds checking altogether.
If you make solid use of assertions, bounds checking internal to your container classes is completely redundant.
Your own assertions provide diagnostics ten times more likely to immediately point to the precise location of the problem.
Bounds checking is what you do after your engineering efforts have failed.
This is so much bullpucky.
The vast majority of the STL algorithms have a natural, efficient expression. I've read as least three different STL algorithm library sources and I didn't find much exceptional in how any of them implemented the basic algorithms.
The most complicated algorithms I can think of right now are the various sorting algorithms. The original HP implementation did a pretty reasonable job in making good use of the heap primitive. In order to implement these algorithms badly you'd need to completely ignore the model implementations.
The containers and the string class are a different matter. I can imagine slow implementations of map and string. In the case of string, it's almost impossible to implement it to be efficient for all cases. But don't blame the algorithms. They are at least as reliable as qsort() or rand() from the C library.
Once upon a time I had a version of Watcom which failed to implement the tail recursion properly and consumed linear stack space. It was widely documented that this is a required practice, but the Watcom programmer didn't bother to consult any precedents. If anything, these problems are less likely to occur in quality STL implementations.
I see no reason why the C++ standard should impose policies, such as error checking, on STL library developers, who have an extremely wide range of interests to serve.
If you want default error checking, obtain an STL implementation that performs default error checking. You don't understand my problems. I don't want your defaults.
My understanding of the history of the STL is that many of the committee members who voted in favor of the STL were extremely impressed by what the generic approach promised.
I agree that the STL containers are not particularly well suited as interface arguments. I find that I rarely do this. Either I create a template algorithm that takes generic iterators, or I pass application class objects directly.
What you have failed to understand is that C++ was designed to serve many different masters. Much of the shape of the STL was chosen to make it possible to build efficient 3rd party libraries on top of the STL algorithms.
These libraries might very well be performing their own error checking at a higher semantic layer. Layers upon layers of error checking finally lead to a completely safe library than no one can afford to use in a production system.
Lisp blows C++ away in high level concepts?
Like what?
The type inference mechanisms in C++ have the full expressive power of a functional language. Type inference in C++ _is_ a functional language (type results are never changed once they are created).
The problem with C++ is not lack of expressive power, but that the expressive power is often difficult to leverage out in its purest form.
A polynomial time map implementation does not conform to the STL standard which makes execution order guarantees.
You presented your issue badly. You should have complained about a violation of the STL execution order requirements until they sent you something non-polynomial.
Chances are they would have solved the problem by improving their algorithm rather than making the insertion of the first element a ten second operation.
1. unacceptable build times and object sizes
The extra burden on the compiler is there for the benefit of the programmer.
Compilers usually lag behind trends in how typical applications are written. It's much easier to improve a compiler when you have a representative code base against which to vet your changes.
All of the problems I'm aware of have good solutions in principle.
2. difficult to derive from STL classes
The STL classes weren't designed to support derivation. The STL is designed so that you can write your own container classes (or class hierarchies) in such a way that they remain compatible with the STL algorithms. The algorithms are the design center of the STL.
In other words, don't do this!
I think small_dick must have done a lot of self moderation to warrant a 5 for that wad of premajaculate.
90% of the ugliness in C++ is due to maintaining downward compatibility with C. That was a strategic decision from the outset, without which C++ most likely would never have become the subject of this thread.
Beyond those defects, it really comes down to whether a programmer is patient enough to cope with static binding and dynamic binding in the same context. Tell me what Java has accomplished when Java has the same expressive power for static bindings.
Any criticism of C++ centered around experience with a Microsoft compiler is pretty much worthless.
Microsoft's support of templates through version 6 was on a rough par with the support in Netscape 3.0 for cascading style sheets.
The generic idioms and implementation blocks are so different from conventional OO structure that you naturally find yourself acquiring different stylistic preferences.
Generic code is largely based on manipulations of types rather than values. Entirely different classes of mistakes are made manipulating types rather than values.
My guess is that the people on your team who were most sensitive to layout issues where the members of the team who were most clued into the fundamentally different expressive nature of generic code.
>> First off, the OTP is completely 100% unbreakable [in theory]. Even with infinite time an OTP is unbreakable.
> Wrong. Given infinite time, a monkey will eventually bang out the contents of the OTP. Nothing is unbreakable given infinite time. Period.
I hope this response will remove the impressive sentence "Period." from your vocabulary for a long, long time. Or maybe it means what it appears to mean: I'm so sure of myself I don't need to think.
The deal with OTP is that the number of possible keys is exactly equal to the number of possible messages. If you try all the keys, you get every possible message. It doesn't matter which message you start with. If you try all the keys you get all the possible messages. Is that progress?
In fact, with OTP the set of all keys is identical to the set of all messages (for a given bit length). By your definition of "break" you don't actually need to capture the encrypted message. The decrypted message is already in your keys file!
There is no way to know when a key you tried produced the correct output. Every output is produced by some key. Every output that is even vaguely plausible is in there. Every output entirely is in there somewhere.
With a roomful of monkeys I can break every message ever written. With an infinite amount of time they'll type out everything ever encrypted. I don't even need the original messages. Cool.
You should write a book: interception made easy. Or maybe you should just dig it out of your keys file. It'll save you the effort of putting your own words together in sensible patterns.
The xor swap only makes sense if you use it to swap a bit field within the integral value.
Off the tip of my fingers I think it goes like this:
b ^= a;
a ^= (b & bitmask);
b ^= a;
Yes, that should be right since if the second statement is rendered idempotent by a zero bit in the bitmask it boils down to this:
b ^= a;
b ^= a;
And we are back to the beginning again.
There's no good reason a compiler couldn't be coded to recognize this sequence of steps and apply instruction level optimizations, such as on x86 if your constant bitmask is just swapping the low byte. The single byte swap instruction could be substituted mechanically.
The program code:
uint32 a, b;
b ^= a;
a ^= (b & 0xFF);
b ^= a;
Would be generated by the compiler as:
swap al, bl
Of course I'm joking that anyone would implement this optimization in a real compiler. But then take a look at recent developments to automate the generation of SIMD instructions for conventionally coded loops.
I think the boundary between what helps and what hinders the compiler is becoming extremely blurry.
The floating point unit doesn't have an xor capability in any modern chip I've seen, unless the IA-64 bit slicing facilities for floating point manipulation include this.