MSVC curiosities

While developing/optimizing RDESTL I found two funny curiosities in Microsoft Visual C++ 2008 (Express).

  1. 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:
    template<typename T>
    void destruct(T* mem, int_to_type)
    {
        mem->~T();
    }
    Compiler will complain about ‘mem’ not being used.
  2. When examining assembly output (with optimization enabled) of this simple function:
    void move(const T* first, const T* last, T* result, int_to_type)
    {
        const size_t bytes = (last - first) * sizeof(T);
        ...
    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:
    mov	eax, DWORD PTR _last$[esp-4]
    sub      eax, DWORD PTR _first$[esp-4]
    push    12			
    pop      ecx
    cdq
    idiv      ecx
    imul	 eax, 12
    Solution is easy, albeit not very elegant:
    const size_t bytes =
        reinterpret_cast(last) -
        reinterpret_cast(first);
    Assembly for this:
    mov	eax, DWORD PTR _last$[esp-4]
    sub	eax, DWORD PTR _first$[esp-4]
    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.

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 […]

More Reading
Newer// RDESTL - SVN
Older// RDESTL