Friday, May 29, 2009

The Horror Returns

I last complained about C++ back in September (on the 20th and 21st). I thought I had seen all the horrors that the new template error checking could produce.

I was wrong.

Check out the new spewage from g++:

main.cpp: In member function `void Test<t>::test()':
main.cpp:11: error: expected `;' before "i"
main.cpp:11: error: `i' undeclared (first use this function)
main.cpp:11: error: (Each undeclared identifier is reported only once for each function it appears in.)
main.cpp: In member function `void Test<t>::test() [with T = int]':
main.cpp:20: instantiated from here
main.cpp:11: error: dependent-name ` std::vector<t,std::allocator<_chart> >::const_iterator' is parsed as a non-type, but instantiation yields a type
main.cpp:11: note: say `typename std::vector<t,std::allocator<_chart> >::const_iterator' if a type is meant


Not bad, 8 lines (some very long) for a 24 line program! Oh, and can I say how much I "love" the <> syntax for templates when it comes time to post into HTML (of course, C++ predates the web, so I can't blame Bjarne too much :)

Here is "teh codz"

#include <vector>
#include <cstdio>

template<typename T>
class Test
{
public:
void test(void)
{
std::vector<T> v;
for(std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
printf("%p\n", &*i);
}
};

int main(int argc, char **argv)
{
Test<int> t;

t.test();

return 0;
}


Line 11 is the 'for' loop. g++ is complaining about the declaration for 'i', which is the standard (ugly) iterator. The note must of been added after lots of people complained.

The core of the error is "parsed as a non-type, but instantiation yields a type". It means that because it uses <T> somewhere, it must be parsed as a non type (that is, g++ has no idea what the type could be at this time). However, it is being used to declare a variable - which must have a type. So, g++ is confused.

The note tells us how to fix it:

$ diff main.bad.cpp main.cpp
11c11
< for(std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
---
> for(typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)

Thanks diff for more < and >! (also predates HTML, so maybe HTML is to blame...)

Of course, if the compiler knows what the problem is well enough to emit the note, and the fix is so easy, makes you wonder why the compiler can't just fix it for you...

No comments: