The function pointer types estimated by template are wrong - by はぴぴ

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 704352 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 11/15/2011 9:02:31 PM
Access Restriction Public
Moderator Decision Sent to Engineering Team for consideration



Steps to reproduceのソースコードは、そのエラーが発生する最小限のコードです。

asyncCaller([]{}); と asyncCaller(&hoge); は期待通りに動作しました。

asyncCaller(hoge); は asyncCaller(&hoge); と同じ結果になることを期待しましたが、実行時エラーとなりました。

デバッガを利用して、asyncCaller(hoge); の行からステップインすると、 f が void (*)(void) となりました。

f は const F & で宣言されたにもかかわらず、const も & も含まない型となりました。

これはバグですか? 仕様ですか?

さらに asyncCaller 内の threadProc(&f); の行からステップインすると、pf も void (*)(void) となりました。

void (*)(void) である変数 f のアドレスを取るために &f と記述したので、pf は void (**)(void) となることを期待しましたが、そうなりませんでした。

これはバグですか? 仕様ですか?

さらに pf は void (*)(void) なので、*pf は void (void) となることが期待され、f2 は void (&)(void) となることを期待しましたが、void (*const &)(void) となりました。

この型は、asyncCaller(&hoge); を実行した場合と同じです。

しかし、f2 のアドレス値は pf と全く異なる値となり、これを呼び出した時点で Actual results に示したメッセージが表示されました。

ウォッチで *(void**)f2 は 0x00a946e9 と表示されたので、エラーメッセージで表示されたアドレスと一致しました。


Operating System Languageでは、Japaneseを見つけられなかったのでEnglishを選択しましたが、実際にはJapaneseです。
Sign in to post a comment.
Posted by はぴぴ on 12/11/2011 at 11:10 PM
Thank you for investigation and consideration of fixing.
Posted by Microsoft on 12/9/2011 at 2:38 PM

Thank you for this feedback. Looks like we do have a bug in local auto initialization for function pointer types. We will consider fixing it in the next release. In the meantime, please consider accepting this workaround if possible.

template<typename F> void threadProc(const F *pf){
template<typename F> void asyncCaller(const F &f){

void hoge(){}
int main(int argc, wchar_t* argv[]){
    asyncCaller([]{}); //OK
    asyncCaller(&hoge); //OK
    asyncCaller(hoge); //OK
    return 0;

Ulzii Luvsanbat
Windows C++ Team
Posted by はぴぴ on 11/28/2011 at 7:48 PM
I think it is the problem of references of function pointer.

const auto &d1 = hoge;    //void hoge(){}
const auto &d2 = *d1;    //ok
const auto &d3 = *d2;    //ok
const auto &d4 = *d3;    //access violation
const auto &d5 = *d4;    //?
const auto &d6 = *d5;    //can comple continually forever

&d1    0x0012fe2c    void (void)* *
d1    0x0045d369 hoge(void)    void (void)*
*d1    0x0045d369 hoge(void)    void (void)
&d2    0x0045d369 hoge(void)    void (void)* const *
d2    0x00ab92e9    void (void)* const &
*d2    0x00ab92e9    void (void)* const
&d3    0x00ab92e9    void (void)* const *
d3    CXX0030: エラーです: 式を評価できません    
*d3    CXX0030: エラーです: 式を評価できません    
&d4    0xcccccccc    void (void)* const *
d4    CXX0030: エラーです: 式を評価できません    
*d4    CXX0030: エラーです: 式を評価できません    

I think d1 ~ d6 should have the type "void (void) *const &", and the same value as e1 ~ e6.

auto e1 = hoge;
auto e2 = *e1;
auto e3 = *e2;
auto e4 = *e3;
auto e5 = *e4;
auto e6 = *e5;

e1    0x0045d369 hoge(void)    void (void)*
e2    0x0045d369 hoge(void)    void (void)*
e3    0x0045d369 hoge(void)    void (void)*
e4    0x0045d369 hoge(void)    void (void)*
e5    0x0045d369 hoge(void)    void (void)*
e6    0x0045d369 hoge(void)    void (void)*
Posted by はぴぴ on 11/23/2011 at 5:42 PM
I found "auto" has a similar problem.

const auto &a1 = &hoge;
const auto &a2 = *a1;
const auto &b1 = hoge;
const auto &b2 = *b1;
typedef void F(void);
F *const &c1 = hoge;
F *const c2 = *c1;
a1();    //ok
a2();    //access violation
b1();    //ok
b2();    //access violation
c1();    //ok
c2();    //access violation

Debugger's Watch
a1    0x0045d32d hoge(void)    void (void)* const &
*a1    0x0045d32d hoge(void)    void (void)* const
a2    0x00a98ee9    void (void)* const &
*a2    0x00a98ee9    void (void)* const
b1    0x0045d32d hoge(void)    void (void)*
*b1    0x0045d32d hoge(void)    void (void)
b2    0x00a98ee9    void (void)* const &
*b2    0x00a98ee9    void (void)* const
c1    0x0045d32d hoge(void)    void (void)* const &
*c1    0x0045d32d hoge(void)    void (void)* const
c2    0x00a98ee9    void (void)* const &
*c2    0x00a98ee9    void (void)* const

"a2" is similar to "asyncCaller(&hoge)", but it is different, and did not work.
"b2" is the same as "asyncCaller(hoge)", and did not work.
I gave "c1" and "c2" the same types as "a1" and "a2".
Then "c2" did not work.

I think those problem is not type estimation but the reference of function pointer.
Posted by MS-Moderator10 [Feedback Moderator] on 11/16/2011 at 1:12 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 investigation. We will contact you if we require any additional information.
Posted by はぴぴ on 11/15/2011 at 10:01 PM
When I wrote a function that executes a function pointer or lambda function given as argument, an unexpected error occured.

The source code in Steps to reproduce is the minimum code that reproduces the error.

asyncCaller([]{}); and asyncCaller(&hoge); worked well.

I expected asyncCaller(hoge); works same as asyncCaller(&hoge);, but runtime error occured.

I used debugger, and stepped in from asyncCaller(hoge);, the type of "f" was void (*)(void).

Though "f" was declared as "const F &", the type was not include "const" nor "&".

Is this bug? or specification?

And When I stepped in from threadProc(&f); in asyncCaller, the type of "pf" was also void (*)(void).

I expected "&f" would be void (**)(void), but it was not so.

Is this bug? or specification?

I expected "*pf" would be void (void), but it became void (*const &)(void).

This type was the same as the case excuting asyncCaller(&hoge);.

But, the address of "f2" was different from pf, and when it was called, the message written in Actual results was shown.

In watch window, "*(void**)f2" was 0x00a946e9, and it was the same as the address in error message.

I think it was bug.
Posted by MS-Moderator01 on 11/15/2011 at 9:45 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(