www.flickr.com
Showing posts with label standard library. Show all posts
Showing posts with label standard library. Show all posts

Monday, November 20, 2006

Visual C++ Tip: Visual C++ is Broken

Once again, I feel the urge to severely beat the people responsible for Visual C++.

I've once again run into examples of severe stupidity in this compiler. It seems that somehow,
Visual C++ got released without someone checking to see if the standard libraries can actually be compiled at the highest warning levels (for Visual C++ 8, that's with the option /Wall).

It really is quite essential for best practices that a compiler can compile it's own standard libraries at the highest warning levels without producing warnings. Otherwise, it causes obfuscation and hides legitimate messages related to the users' code. What's worse, the warnings produced from the standard library are completely opaque.

Here's an example of the warnings I've been given by the compiler.
C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\string.h(141) : warning C4619: #pragma warning: there is no warning number '4609'
C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\wchar.h(116) : warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::attrib'
C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\wchar.h(121) : warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::name'
The first one is a real gem. A warning that there's a warning that doesn't exist. And I think the second one is an indication that there's a nasty shortcut for memory initialisation somewhere. Ugh.

The only lesson here is that the compiler option /Wall is completely unusable. So, use /W4 instead. It's less rigorous, but at least, there's fewer strange warnings emitted from the compiler regarding the standard library at that level. Few enough that they can be disabled or filtered out.

Friday, November 17, 2006

Visual C++ Tip: How to Enable Standard C++ Keywords

The people at Microsoft responsible for Visual C++ need to beaten with a stick. Those responsible for the documentation should be beaten severely.

Once again, I just finished another round of frustration with the non-compliance problems of Visual C++ 8. One would think that by six years after the ISO standard, they would get around to having all the embarrassingly glaring compliance issues sorted out, but sadly, it is still the case that simple, conforming C++ programs will not easily compile.

My current frustration is that, by default, Visual C++ has the boolean operator keywords disabled. That's right, by default, Visual C++ has certain, standard C++ keywords disabled. And it isn't some obscure functionality that I'm referring to, it's the keywords for the logical boolean operators.

It is possible to enable them with the option /Za. To be clear on this, we can refer to the MSDN documentation for the /Za option,
/Za flags language constructs not compatible with either ANSI C++ or ANSI C as errors. /Ze enables Microsoft extensions.
Uh oh, it looks like Microsoft tied two bits of unrelated functionality together into one compiler option, and left one of the bits undocumented. I think I have the full story figured out now, but caveat lector! We've landed in an undocumented, side-effect territory. It seems that we can either have the standard keywords or the language extensions, but not both. Now, most of the language extensions are useless, losing them is no problem, but there is an exception here. The keyword "extern" is erroneously considered a language extension by Microsoft. If you need that very useful keyword, you may run into problems.

Like I wrote at the start of this post, the people at Microsoft responsible for Visual C++ need to beaten with a stick. Those responsible for the documentation should be beaten severely. The design choice here is a shining example as to just how bad the compiler actually is.

Thursday, October 26, 2006

C++ Tip: Stream Iterators

Problem
Write an item n times to an output stream

Solution A: Write a for loop

data_type x = value
for (unsigned int i = 0; i > n; ++i)
  std::cout << x;

Solution B: Use an iterator and an algorithm
std::fill_n(std::ostream_iterator<data_type>(std::cout), n, x);

Discussion
Solution A has the advantage of simplicity. Almost everyone can remember how to code a for loop. However, Solution B serves as a neat, albeit somewhat trivial, example of the use of a stream iterator working with an algorithm. This is a powerful combination that is rarely explored. So, next time there's something interesting to be done with streams, remember that there is a lot of potential in using the algortihms in the standard library.

Addendum
I ran some tests to see how the performance of the two solutions compare. With g++ 3.4.2 (mingw-special), there's no difference, regardless of the optimisation options. So, do not hesitate to use the standard library for fear of poor performance.