Home Dashboard Directory Help
Search

VC++ 2010: Explicit template arguments cause type disagreement for types that decay to pointers by Joshua Burkholder


Status: 

Closed
 as By Design Help for as By Design


1
0
Sign in
to vote
Type: Bug
ID: 647035
Opened: 2/24/2011 4:26:32 PM
Access Restriction: Public
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

Explicit template arguments cause type disagreement for types that decay to pointers (function types and array types). Based on the function-type specific code in the "Steps to reproduce" section, since we have F ff as the parameter of the is_F_same_as_decltype_ff() function, it seems like F should __always__ agree with decltype( ff ). In other words, the bug is that there is type disagreement when explicit template arguments are used (esp. when there is no type disagreement when implicit template arguments are deduced). Perhaps both F and decltype( ff ) should both decay to pointer types ... even if F is an explicit template argument that is not a pointer type. Or perhaps both F and decltype( ff ) should both be of type F ... irregardless of the adjustment that takes function & array types down to pointers. Either way, this type disgreement is currently inconsistent and non-intuitive.

The same can be shown for array types as well ... in other words, if we use say char[3] (i.e. a c string) instead of void (), then we get the same type of type disagreement ( char[3] versus char * ). See my main.cpp file from 2/24/2011 for an example of type disagreement using character arrays.

Note: If we compile and run the code in the "Steps to reproduce" section with g++ 4.5.2, then we get the expected output (i.e. the output in the "Expected results" section) ... which is currently different than what VC++ 2010 currently produces (i.e. the output in the "Actual results" section).

This type disagreement effects the use of sizeof() as well. See my main.cpp from 2/25/2011 for an example sizeof() disagreement. Both VC++ 2010 and g++ 4.5.2 seem to suffer from this inconsistency ... albeit, in different ways.
Details
Sign in to post a comment.
Posted by Microsoft on 2/28/2011 at 9:27 AM
Thank you for reporting this issue to Microsoft. Here's an analysis done by one of our developers:

I believe that VC's behavior is CORRECT. Here is a modified repro:


C:\Temp>type meow.cpp
#include <ios>
#include <iostream>
#include <ostream>
#include <type_traits>
using namespace std;

template <typename T> struct stringify;

template <> struct stringify<void ()> {
    static const char * str() { return "void ()"; }
};

template <> struct stringify<void (*)()> {
    static const char * str() { return "void (*)()"; }
};

template <typename F> void meow(F ff) {
    (void) ff;

    cout << "         F: " << stringify<F>::str() << endl;
    cout << "decltype(ff): " << stringify<decltype(ff)>::str() << endl;
    cout << "     is_same: " << is_same<F, decltype(ff)>::value << endl;

    cout << endl;
}

void f() { }

int main() {
    cout << boolalpha;

    cout << "meow(f)" << endl;
    meow(f);

    cout << "meow<void (*)()>(f)" << endl;
    meow<void (*)()>(f);

    cout << "meow<decltype(f)>(f)" << endl;
    meow<decltype(f)>(f);

    cout << "meow<void ()>(f)" << endl;
    meow<void ()>(f);
}

C:\Temp>cl /EHsc /nologo /W4 meow.cpp
meow.cpp

C:\Temp>meow
meow(f)
         F: void (*)()
decltype(ff): void (*)()
     is_same: true

meow<void (*)()>(f)
         F: void (*)()
decltype(ff): void (*)()
     is_same: true

meow<decltype(f)>(f)
         F: void ()
decltype(ff): void (*)()
     is_same: false

meow<void ()>(f)
         F: void ()
decltype(ff): void (*)()
     is_same: false




N3225 7.1.6.2 [dcl.type.simple]/4 says: "The type denoted by decltype(e) is defined as follows: — if e is an unparenthesized id-expression or a class member access (5.2.5), decltype(e) is the type of the entity named by e."



8.3.5 [dcl.fct]/5 says: "After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively."



This "adjustment" happens before sizeof (which can easily be verified with arrays adjusted to pointers), so it should happen before decltype too.

Regards,

Tanveer Gani
Visual C++ Team
Posted by Microsoft on 2/25/2011 at 2:23 AM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by Microsoft on 2/24/2011 at 7:14 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
File Name Submitted By Submitted On File Size  
main.cpp 2/24/2011 10 KB
main.cpp 2/25/2011 4 KB