2014-09-05 34 views
7

staram oficjalne wdrożenie nullptrproblemy w realizacji nullptr na VS2013

wiem z nullptr i std :: nullptr_t obsługiwanym przez kompilatory, to realizacja jest meaningless.I jestem po prostu staramy się uczyć C++.

i wszystko działa dobrze przez GCC4.9.1 na moim komputerze, zarówno -std = C++ 03, jak i -std = C++ 11, a nawet udane Online @ ideone.com GCC4.3.2.

ale zgodne VS2013 125 idzie error2440, konwersja powiodła

error C2440: "initialize": cannot convert "const <unnamed-type-my_nullptr>" to "int (__thiscall Test::*)(void) const" in line125 

>

#include <iostream> 
#include <cassert> 

// The Official proposal 
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf 
const // this is a const object... 
class { 
public: 
    template<class T> // convertible to any type 
    operator T*() const // of null non-member 
    { 
     return 0; 
    } // pointer... 

    template<class C, class T> // or any type of null 
    operator T C::*() const // member pointer... 
    { 
     return 0; 
    } 

private: 
    void operator&() const; // whose address can't be taken 
} my_nullptr = {}; // and whose name is nullptr 


struct Test123 { 
    int ABCD, ABC, AB; 
    int A; 
    int BA, CBA, DCBA; 
    struct XYZ { 
     char X, Y, Z, W; 
    }; 
    struct { 
     int B, C, D; 
    }; 
} test123; 


class Test { 
    int ABCD; 
public: 
    void method(void){} 

    Test(int val) :ABCD(val){} 
    int getABCD(void) const { return ABCD; } 
    int get2ABCD(void) const { return ABCD * 2; } 
    int get3ABCD(void) const { return ABCD * 3; } 
} test(0123); 


int main(int argc, char* argv[]) 
{ 

    // TEST_my_nullptr 
    { 
     int a = 321, *p = my_nullptr; 
     assert(p == my_nullptr); 
     assert(my_nullptr == p); 

     p = &a; *p = 0123; 
     assert(p != my_nullptr); 
     assert(my_nullptr != p); 

     p = my_nullptr; 

     int(*mainptr)(int argc, char** argv) = my_nullptr; 
     assert(mainptr == my_nullptr); 
     assert(my_nullptr == mainptr); 
    } 


    // TEST_my_nullptr_const 
    { 
     const int a = 321, *p = my_nullptr; 
     assert(p == my_nullptr); 
     assert(my_nullptr == p); 

     p = &a; 
     assert(p != my_nullptr); 
     assert(my_nullptr != p); 

     const int** ptr = my_nullptr; 

     assert(ptr == my_nullptr); 
     assert(my_nullptr == ptr); 

     ptr = &p; 
     assert(ptr != my_nullptr); 
     assert(my_nullptr != ptr); 
     assert(*ptr != my_nullptr); 
     assert(my_nullptr != *ptr); 

    } 


    // TEST_my_nullptr_member 
    { 
     int Test123::*pINT = my_nullptr; 
     assert(pINT == my_nullptr); 
     assert(my_nullptr == pINT); 

     pINT = &Test123::ABCD; 
     assert(pINT != my_nullptr); 
     assert(my_nullptr != pINT); 

     test123.*pINT = 0123; 

     const int Test123::*pCINT = my_nullptr; 
     assert(pCINT == my_nullptr); 
     assert(my_nullptr == pCINT); 

     pCINT = &Test123::ABCD; 
     assert(pCINT != my_nullptr); 
     assert(my_nullptr != pCINT); 

     assert(test123.*pCINT == test123.*pINT); 
    } 

    // TEST_my_nullptr_Function 
    { 
     void (Test::*pm)(void) = &Test::method; 

     pm = my_nullptr; 

     > int (Test::*pABCD)(void) const = my_nullptr; // This Fxxk Line In VS2013 

     pABCD = &Test::getABCD; 

     int a1 = (test.*pABCD)(); 

     pABCD = &Test::get2ABCD; 
     int a2 = (test.*pABCD)(); 

     pABCD = &Test::get3ABCD; 
     int a3 = (test.*pABCD)(); 

     assert(a1 + a2 == a3); 
    } 

    std::cout << "All Tests for my_nullptr Passed!" << std::endl; 
    return 0; 
} 

my Testsuit in GCC4.3.2

+5

Wyraźnie pokazują, w którym linia pojawi się błąd i pokazywać pełny komunikat o błędzie. – Jarod42

+1

Masz anonimową strukturę w swoim kodzie. –

+1

Wygląda na błąd MS na 'const' zmiennej' pABCD'. Może zgłosić raport o błędzie na http://connect.microsoft.com? – Niall

Odpowiedz

1

Prawdopodobnie jest to błąd w VS2013. Wygląda na to, że błąd został naprawiony w CTP VS14, gdzie twój kod kompiluje się bezbłędnie.

0

To niestety nie jest tak źle zachowanie. Ponieważ MS jest z jego kompilatorami nie jest najszybszy, a także nie jest to interpretacja standardów, prawie nigdy nie są blisko.

tj. Zwykły kompilator C MSVC2013 jest mieszanką klauzul c89 i c99 z wieloma dodatkowymi wyjątkami jako nieobsługiwanymi rzeczami, standard podaje, że AC kompilator ma HAS do obsługi, a także ma wiele cech, które według standardu AC kompilator NIE JEST DOZWOLONY .

Więc nie polegaj na standardach podczas kompilowania aplikacji c lub C++ z kompilatorem Microsoft Visual C.

(to pewnie dlatego nazywają go Visual C, a oni nawet nie wolno nazwać to zwykły C;))