allocator + destroy



  • Hallo... ^^

    Ich hab gerad nen eher kleinen schönheitsfehler...

    nen destroy ist ja üblicherweise so aufgebaut

    void destroy(pointer p)
    {
    	p->~value_type();
    }
    

    so bald man den allocator dann aber für nen POD nutzt, bekommt man (weil es eben keinen dtor gibt) ne warning im msvc... (#4100 - unreferenced formal parameter)

    klar kann ich das mit pragma`s deaktivieren, aber geht es nicht irgendwie auch eleganter? und eben vor allem halt auch für andere compiler ^^

    der einzige weg, der mir einfallen würde, wäre mit boost::IsPod zu arbeiten und destroy entsprechend zu spezialisieren - aber für die eine warnung ist mir das iwie zu viel arbeit 😉

    edit: und wenn wir schon mal dabei sind noch ne frage zu max_size:

    _SIZT max_size() const _THROW0()
    	{	// estimate maximum array size
    	_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
    	return (0 < _Count ? _Count : 1);
    	}
    

    wieso wird dort dieser vergleich durchgeführt? wieso soll ein objekt erstellt werden können, wenn das objekt größer ist, als der addressraum überhaupt sein kann?
    meins würde so aussehen:

    size_type max_size() const
    {
    	size_type addresses = size_type(~0);
    	size_type object_size = sizeof(T);
    	return addresses/object_size;
    }
    

    bb


  • Administrator

    unskilled schrieb:

    so bald man den allocator dann aber für nen POD nutzt, bekommt man (weil es eben keinen dtor gibt) ne warning im msvc... (#4100 - unreferenced formal parameter)

    klar kann ich das mit pragma`s deaktivieren, aber geht es nicht irgendwie auch eleganter? und eben vor allem halt auch für andere compiler ^^

    Naja, in der Standardbibliothek des MSVC steht:

    #ifdef  _MSC_VER
     #pragma pack(push,_CRT_PACKING)
     #pragma warning(push,3)
     #pragma warning(disable: 4100) // <- - - - - ;)
    #endif  /* _MSC_VER */
    

    Wenn man dann noch die Dokumentation zu der Warnung liest:
    http://msdn.microsoft.com/en-us/library/26kb9fy0.aspx

    Dann sollte man diesen Satz sehen:

    MSDN schrieb:

    C4100 can als be issued when code calls a destructor on a otherwise unreferenced parameter of primitive type. This is a limitation of the Visual C++ compiler.

    Grundsätzlich sollte keine Warnung geworfen werden. Die Warnung bedeutet schliesslich nicht, dass man keinen Destruktor eines PODs aufrufen darf, sondern dass die Variable nicht referenziert wird, also im Code nicht benötigt. Das stimmt allerdings gar nicht und ist halt eben ein Fehler des Visual C++ Kompilers.

    unskilled schrieb:

    edit: und wenn wir schon mal dabei sind noch ne frage zu max_size:

    _SIZT max_size() const _THROW0()
    	{	// estimate maximum array size
    	_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
    	return (0 < _Count ? _Count : 1);
    	}
    

    wieso wird dort dieser vergleich durchgeführt? wieso soll ein objekt erstellt werden können, wenn das objekt größer ist, als der addressraum überhaupt sein kann?

    max_size soll laut Standard einen Wert zurückgeben, welcher sinnvoll an die Methode allocate übergeben werden darf. Der Standard sagt auch, dass das übergeben von 0 an die Methode allocate einen undefinierten Rückgabewert hat.
    Ich könnte mir vorstellen, dass die Entwickler der Standardbibliothek im MSVC gedacht haben, dass sie nicht noch per if eine an allocate übergebene 0 abfangen wollen, sondern gleich die Tatsache ausnützen, dass wenn zu wenig Speicher vorhanden ist, eine std::bac_alloc Exception geworfen wird.

    Zudem ganz ehrlich: Was für ein riesiges Objekt sollte das sein? Ein Objekt, welches den ganzen Speicher füllt? Und dass noch in einem Container oder ähnlichem? LoL 🙂

    Grüssli



  • Dravere schrieb:

    unskilled schrieb:

    so bald man den allocator dann aber für nen POD nutzt, bekommt man (weil es eben keinen dtor gibt) ne warning im msvc... (#4100 - unreferenced formal parameter)

    klar kann ich das mit pragma`s deaktivieren, aber geht es nicht irgendwie auch eleganter? und eben vor allem halt auch für andere compiler ^^

    Naja, in der Standardbibliothek des MSVC steht:

    #ifdef  _MSC_VER
     #pragma pack(push,_CRT_PACKING)
     #pragma warning(push,3)
     #pragma warning(disable: 4100) // <- - - - - ;)
    #endif  /* _MSC_VER */
    

    Japp - allerdings hätt es ja auch sein können, dass es nen anderen Trick gibt - aber wenn andere Compiler diesen Fehler nicht haben, ists ja ok 🤡

    Dravere schrieb:

    unskilled schrieb:

    edit: und wenn wir schon mal dabei sind noch ne frage zu max_size:

    _SIZT max_size() const _THROW0()
    	{	// estimate maximum array size
    	_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
    	return (0 < _Count ? _Count : 1);
    	}
    

    wieso wird dort dieser vergleich durchgeführt? wieso soll ein objekt erstellt werden können, wenn das objekt größer ist, als der addressraum überhaupt sein kann?

    max_size soll laut Standard einen Wert zurückgeben, welcher sinnvoll an die Methode allocate übergeben werden darf. Der Standard sagt auch, dass das übergeben von 0 an die Methode allocate einen undefinierten Rückgabewert hat.
    Ich könnte mir vorstellen, dass die Entwickler der Standardbibliothek im MSVC gedacht haben, dass sie nicht noch per if eine an allocate übergebene 0 abfangen wollen, sondern gleich die Tatsache ausnützen, dass wenn zu wenig Speicher vorhanden ist, eine std::bac_alloc Exception geworfen wird.

    OK - das klingt logisch - danke 🙂

    Dravere schrieb:

    Zudem ganz ehrlich: Was für ein riesiges Objekt sollte das sein? Ein Objekt, welches den ganzen Speicher füllt? Und dass noch in einem Container oder ähnlichem? LoL 🙂

    Ich hatte mich eben nur gewundert ^^
    Mir schon klar, dass es ein noch theoretischeres Problem ist als beispielsweise bad_alloc...

    bb


  • Administrator

    unskilled schrieb:

    ... - aber wenn andere Compiler diesen Fehler nicht haben, ists ja ok 🤡

    Sie sollten zumindest nicht, da dieses Vorgehen vollständig definiert ist. Der MSVC beklagt sich ja auch nicht über das Vorgehen.

    Im Standard steht dazu:

    C++ Standard 14882:2003 - 5.2.4 Pseudo destructor call schrieb:

    1 The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the
    non-class type named by type-name. The result shall only be used as the operand for the function call oper-
    ator (), and the result of such a call has type void. The only effect is the evaluation of the postfix-
    expression before the dot or arrow.
    2 The left hand side of the dot operator shall be of scalar type. The left hand side of the arrow operator shall
    be of pointer to scalar type. This scalar type is the object type. The type designated by the pseudo-
    destructor-name shall be the same as the object type. Furthermore, the two type-names in a pseudo-
    destructor-name of the form
    ::optnested-name-specifieropt type-name :: ˜ type-name
    shall designate the same scalar type. The cv-unqualified versions of the object type and of the type desig-
    nated by the pseudo-destructor-name shall be the same type

    Man erkennt in der Aussage des Standards, wieso wohl auch der MSVC diese Warnung wirft. Es soll nur den Postfix-Ausdruck vor dem Punkt oder Pfeil ausgewertet werden. Das ist bei dir aber nur eine alleinstehende Variable, daher sieht der MSVC dies nicht als eine genutzte Variable an und es kommt zur Warnung.

    Grüssli


Log in to reply