MSVC curiosities
29/Nov 2007
While developing/optimizing RDESTL I found two funny curiosities in Microsoft Visual C++ 2008 (Express).
- All my home projects are compiled with maximum warning level and warnings treated as errors. One of the additional warnings in this setting are unused variables. MSVC is a little bit oversensitive, though, because it doesnt treat calling a destructor as ‘using’. Example:
Compiler will complain about ‘mem’ not being used.
template<typename T> void destruct(T* mem, int_to_type) { mem->~T(); }
- When examining assembly output (with optimization enabled) of this simple function:
I found out that MSVC is doing it in an indirect way. It’ll first convert number of bytes to number of elements (dividing (last - first) by sizeof(T)) and then convert it back to number of bytes. Here’s assembly for this fragment:
void move(const T* first, const T* last, T* result, int_to_type) { const size_t bytes = (last - first) * sizeof(T); ...
Solution is easy, albeit not very elegant:mov eax, DWORD PTR _last$[esp-4] sub eax, DWORD PTR _first$[esp-4] push 12 pop ecx cdq idiv ecx imul eax, 12
Assembly for this:const size_t bytes = reinterpret_cast(last) - reinterpret_cast(first);
Not that it matters much :). It shows that compilers are not all that smart (yet), so it may be a good idea to examine generated code from time to time.mov eax, DWORD PTR _last$[esp-4] sub eax, DWORD PTR _first$[esp-4]
Old comments
imul 2010-04-01 23:07:34
[…] (ignoring flag … Of course, most compilers are going to generate the full 32-bit imul. …MSVC curiosities | .mischief.mayhem.soap.While developing/optimizing RDESTL I found two funny curiosities in Microsoft Visual C++ 2008 […]