Здравствуйте, Chorkov, Вы писали:
C>Есть ли гарантии, что константный строковый литерал доживет до конца времени жизни программы?
Да.
C> std::map< const char* , size_t > counters;
Но нет никаких гарантий, что идентичные литералы должны обязательно иметь идентичные адреса. Поэтому, например, в твоём коде финальный размер словаря counters может принимать любое значенеие от 3 до 9 (в зависимости от деталей реализации).
Здравствуйте, watchmaker, Вы писали:
W>Здравствуйте, Chorkov, Вы писали:
C>>Есть ли гарантии, что константный строковый литерал доживет до конца времени жизни программы? W>Да.
C>> std::map< const char* , size_t > counters; W>Но нет никаких гарантий, что идентичные литералы должны обязательно иметь идентичные адреса. Поэтому, например, в твоём коде финальный размер словаря counters может принимать любое значенеие от 3 до 9 (в зависимости от деталей реализации).
Это меня не очень волнует.
Проблема в том, что по выходе из foo литерал, похоже умер. Во всяком случа в foo()[0] — мусор.
Хочу понять, ошибка компилятора или моя.
Здравствуйте, Chorkov, Вы писали:
C>Проблема в том, что по выходе из foo литерал, похоже умер. Во всяком случа в foo()[0] — мусор. C>Хочу понять, ошибка компилятора или моя.
Умер не литерал, а объект класса record, вместе с инкапсулированным указателем.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Chorkov, Вы писали:
C>>Проблема в том, что по выходе из foo литерал, похоже умер. Во всяком случа в foo()[0] — мусор. C>>Хочу понять, ошибка компилятора или моя.
R>Умер не литерал, а объект класса record, вместе с инкапсулированным указателем.
Но, функция возвращает указатель именно на литерал.
Какая разница в каких живых и мертвых объектах побывала копия этого указателя?
Здравствуйте, Chorkov, Вы писали:
C>>>Проблема в том, что по выходе из foo литерал, похоже умер. Во всяком случа в foo()[0] — мусор. C>>>Хочу понять, ошибка компилятора или моя.
R>>Умер не литерал, а объект класса record, вместе с инкапсулированным указателем.
C>Но, функция возвращает указатель именно на литерал. C>Какая разница в каких живых и мертвых объектах побывала копия этого указателя?
Так она возвращает его уже после того, как владеющий объект record уже умер. И на том месте, где раньше был указатель, находится стековый мусор:
Здравствуйте, rg45, Вы писали:
R>>>Умер не литерал, а объект класса record, вместе с инкапсулированным указателем.
C>>Но, функция возвращает указатель именно на литерал. C>>Какая разница в каких живых и мертвых объектах побывала копия этого указателя?
R>Так она возвращает его уже после того, как владеющий объект record уже умер. И на том месте, где раньше был указатель, находится стековый мусор:
R>https://ideone.com/Igl57i
разрушение идет после того как указатель поместился мапу.
Здравствуйте, B0FEE664, Вы писали:
BFE>И что с того? Сам литерал остался жить и адрес его не менялся. Значит и указатель на "a" должен остаться валидным.
Адрес остался валидным. А указатель — область памяти хранившая этот адрес — к тому времени уже используется для чего-то другого.
Здравствуйте, night beast, Вы писали:
R>>https://ideone.com/Igl57i
NB>разрушение идет после того как указатель поместился мапу.
Ну вот я бы не был так уверен. Даже если в примере по ссылке это так, не факт, что это так в примере у ТС.
Главный вывод, который следует сделать, это то, что initializer_list до конца цикла не доживает. А значит и уверенности, что в момент записи в мапу элемент еще жив, быть не может.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Ну вот я бы не был так уверен. Даже если в примере по ссылке это так, не факт, что это так в примере у ТС.
В твоем примере деструкторы вызываются для временных объектов, создаваемых в цикле.
Здравствуйте, dead0k, Вы писали:
R>>Ну вот я бы не был так уверен. Даже если в примере по ссылке это так, не факт, что это так в примере у ТС. D>В твоем примере деструкторы вызываются для временных объектов, создаваемых в цикле.
Здравствуйте, rg45, Вы писали: R>А указатель — область памяти хранившая этот адрес — к тому времени уже используется для чего-то другого.
Согласен. Но перед тем как указатель начал использоваться для чего-то другого его значение было скопировано.
Код примера равносилен следующему:
Здравствуйте, Chorkov, Вы писали:
C>Это меня не очень волнует.
C>Проблема в том, что по выходе из foo литерал, похоже умер. Во всяком случа в foo()[0] — мусор. C>Хочу понять, ошибка компилятора или моя.
А точно при выходе из foo(), а не какой-то реальной функции, где было что-то отличное от return counters.begin()->first; ?
Здравствуйте, B0FEE664, Вы писали:
BFE>Согласен. Но перед тем как указатель начал использоваться для чего-то другого его значение было скопировано.
Ну да, я понял уже свою заблуждение. Я же как раз и предолагал, что указатель портится еще до копирования (помещения в мапу). Теперь мы убедились, что это не так — на gcc. Но ТС утверждает, что у него программа таки не работает, как ожидается. И, прежде, чем прийти к заключению, что портится именно литерал (что лично мне кажется мало вероятным), я бы все-таки убедился, что initializer_list доживает до конца цикла — на его компиляторе!
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Chorkov, Вы писали:
C>Есть ли гарантии, что константный строковый литерал доживет до конца времени жизни программы?
оно статик сторедж, но нет гарантий что один и тот же
C>Изменилось ли что-то в последних стандартах?
Можно с помощью C++11 сконвертировать литерал в шаблонный класс чарактеров, а потом обратно, что будет гарантировать один и тот же адрес.
Фокус с захватом здесь: https://github.com/boostorg/hana/blob/master/include/boost/hana/string.hpp#L102
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, watchmaker, Вы писали:
W>Здравствуйте, Chorkov, Вы писали:
C>>Есть ли гарантии, что константный строковый литерал доживет до конца времени жизни программы? W>Да.
Здравствуйте, B0FEE664, Вы писали:
BFE>Согласен. Но перед тем как указатель начал использоваться для чего-то другого его значение было скопировано. BFE>Код примера равносилен следующему:
Я просто грешным делом попутал две разные проблемы. То, о чем думал я, показано в примере ниже: объект мапы не доживает до конца цикла.
C>Есть ли гарантии, что константный строковый литерал доживет до конца времени жизни программы?
Он доживет до конца времени нахождения в памяти данного бинарника: shared object/dll может быть выгружен задолго до завершения программы, а с ним уйдут и его литерали.
Как много веселых ребят, и все делают велосипед...