C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Function only accepts parameter that will persist

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Mon, 29 Apr 2024 15:08:27 +0200
Hi Frederick,   normally even for static (storage duration) variables a destructor is called at the end of the program. So you would have to make sure those destructors are called in the right order. This is possible by a) scope hierarchy or b) class member order or c) by ownership.     To make it simpler, one would probably limit this feature to work with variables with constant initialization (https://en.cppreference.com/w/cpp/language/constant_initialization). Those variables basically can be constructed during compile-time and stored in read-only memory.   Effectively you introduce constexpr parameter types as suggested by    - P1045 constexpr Function Parameters by David Stone (https://github.com/cplusplus/papers/issues/603)  - P2781 std::constexpr_wrapper by Matthias Kretz & Zach Laine (https://github.com/cplusplus/papers/issues/1458)     To make it more complete, one would change the language to better statically follow and guarantee lifetime dependencies even beyond the aforementioned a) to c). This is related to lifetime safety enhancements of C++.     Best, Sebastian   -----Ursprüngliche Nachricht----- Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Mo 29.04.2024 14:43 Betreff:[std-proposals] Function only accepts parameter that will persist An:std-proposals <std-proposals_at_[hidden]>; CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>; Last week I was programming a microcontroller that had run out of heap memory. There was a global 'std::map' object which mapped the name of a command (e.g. "VERSION") to the address of the function that handled that command, as follows:    std::map< String, bool(*)(bool) > g_command_map; I looked through the code to see where commands were being added to the map, and I saw that every single one of them was a static-duration constant string, using "operator[]" as follows:    g_command_map["VERSION"] = &CommandHandler_Version; Therefore the copying of the string into a heap-allocated 'String' object was unnecessary. So I was able to write my own 'Map' class that just stored a pointer to a null-terminated string, and I wrote 'Map::operator[]' to use 'std::strcmp' to check for equality. Of course though, my new map class would malfunction if you gave it either:    (1) A pointer to a static-duration string which would later change    (2) A pointer to a stack string    (3) A pointer to a heap string which would later change    (4) A pointer to a heap string which would later be deallocated Has anyone ever explored the idea of having a way of defining a function which receives a pointer to an object which is guaranteed to exist forever? So instead of having:    void MyMapClass::operator[](char const *); We might have something like:    void MyMapClass::operator[](static char const *); And so if you were to try to invoke the latter as follows:    int main(void)    {        char str[] = "donkey";        str[0] = 'm';        mymap[str] = 123;        str[0] = 'z';    } then you would get a compiler error because the object referred by the decayed 'str' is not of static duration. Similarly the following would give a compiler error:    int main(void)    {        char *const str = new char[16u];        strcpy(str, "monkey");        mymap[str] = 123;    } In order to get the above snippet to compile, you would need to express your guarantee to the compiler that the object referred by 'str' will exist forever, perhaps by just writing 'static' before the argument:    int main(void)    {        char *const str = new char[16u];        strcpy(str, "monkey");        mymap[ static str ] = 123;    } We would of course though need to consider the possibility of bugs being introduced by programmers mis-using the 'static' keyword in this context -- for example let's say you were to guarantee the immortality of an object and then later deallocate it before the program ends. Next we would have to discuss what effect 'const' has in the following function signature:    void MyMapClass::operator[](static char const *); Does the 'const' mean that the function won't modify the string, or does it mean that the string is guaranteed not to be changed elsewhere for the remainder of the program? Well, here we could use 'const' with 'mutable' as follows:    void MyMapClass::operator[](static char*) - Function cannot alter object, but other functions can    void MyMapClass::operator[](static char const*) - Function cannot alter object, nor can other functions    void MyMapClass::operator[](static char mutable*) - Function can alter object, and so can other functions    void MyMapClass::operator[](static char mutable const*) - Function can alter object, but other functions cannot We could also allow overloading, so that we could have two functions as follows:    void MyMapClass::operator[](static char const *const p, int const x)    {        // No need to copy the string in here    }    void MyMapClass::operator[](char const *const p, int const x)    {        // We must copy the string in here        char *const q = new char[strlen(p) + 1u];        std::strcpy(q,p);        (*this)[static q] = x;  // Invoke the above function    } And we'd have to discuss how long "forever" lasts? Does it mean to the end of the program? Or does it just mean until right before all of the "atexit" registered functions are called? Of course this is just a half-baked idea that I wish to float on the mailing list to see if anyone can see any merit in it. -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals  

Received on 2024-04-29 13:08:30