Why can creating a static const std::string cause an exception?

孤街醉人 提交于 2020-01-12 11:51:15

问题


I have string constants, for strings that I use in multiple places in my app:

namespace Common{
    static const std::string mystring = "IamAwesum";
}

When posting a question about something else (What happens to a .h file that is not included in a target during compilation?), another user made the following comment :

be aware that your static string are global in this case. So they are could create an exception at anytime and can't be catch. I advise you to use function who return a reference of your string. std::string const &mystring { static std::string const mystring = "IamAwesum"; return mystring} by this way your object is only construct when needed

Can someone explain why using static const strings in the manner that I do so above, risks throwing exceptions ?


回答1:


N4140 § 3.6.2 [basic.start.init]/ 4

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main.

N4140 § N4140 15.3 [except.handle]/ 13

Exceptions thrown in destructors of objects with static storage duration or in constructors of namespace-scope objects with static storage duration are not caught by a function-try-block on main().

You simply cannot catch an exception generated by the string's constructor - say, std::bad_alloc.

(opinion) That being said, for such small strings I find this kind of consideration to be paranoid.




回答2:


The pdf document mostly refers to exceptions from the object ctor and initialization order fiasco with static or dynamically linked libraries.

The only danger I see in your code for exceptions is if the ctor of std::string will throw when it is called.

If you want to really be on the safe side you can use static const char* mystring instead which will not call to a C++ ctor.

There is also the matter of the code being in a shared library which then needs to be placed in the address space of the process. I don't see that as a major problem if you don't use complicated ctors(ctors that can throw).




回答3:


The only "issue" -- if you can call it that -- which I see with your code is that you are being wasteful by needlessly copying data that is already constant into a dynamically allocated buffer (which is formally constant, but not in reality). This uses twice as much physical memory as necessary and does a needless copy.

Does it matter? Almost certainly, no. Even on a "rather limited memory" system, this will nowadays hardly be noticeable, neither from an execution time point of view, nor by its memory consumption.

As for exceptions, it is of course technically true that the allocation that std::string has to make could fail, and therefore the constructor could throw, and you wouldn't be able to catch it. But please be realistic.
This is almost guaranteed not to happen, but even if it does... if something as trivial as allocating memory for a couple of string fails while your program starts up, you have a really, really serious issue on a completely different scale!
Besides, as pointed out in a comment on another answer above: Assuming this does happen, what are you going to do about it? The program is utterly unable to run, so there's not much short of killing the program that you could conceivably do.

Now, with C++17 not being far away and string_view already being available in std::experimental on several mainstream compilers, there's another thing you could try: Use the correct thing.

A string_view will, contrary to a string, not allocate non-constant memory, copy constant data into that, and then pretend it's constant. Instead, it will manage a pointer directly to the constant data, and that's all.
That way, your constants are truly (not just formally) constant, there are no allocations, no possibility of exceptions, and no double memory usage. And for the most part, it still looks and smells like a string. The only notable differences being that a string_view doesn't guarantee nul-termination (but the character constant it points to does, so this is irrelevant), and the fact that it's really constant, not modifiable... which is exactly what you want.



来源:https://stackoverflow.com/questions/40377546/why-can-creating-a-static-const-stdstring-cause-an-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!