Skip to main content
added 1114 characters in body
Source Link
L. F.
  • 20.9k
  • 9
  • 57
  • 85

There is no problem with your observation. [basic.stc.static]/2 prohibits eliminating variables with static storage duration:

If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].

This restriction is not present for other storage durations. In fact, [basic.stc.thread]/2 says:

A variable with thread storage duration shall be initialized before its first odr-use and, if constructed, shall be destroyed on thread exit.

This suggests that a variable with thread storage duration need not be constructed unless odr-used.


But why is this discrepancy?

For static storage duration, there is only one instance of a variable per program. The side effects of construction thereof can be significant (kinda like a program-wide constructor), so the side effects are required.

For thread local storage duration, however, there is a problem: an algorithm may start a lot of threads. For most of these threads, the variable is completely irrelevant. It would be hilarious if an external physics simulation library that calls std::reduce(std::execution::par_unseq, first, last) ends up creating a lot of foo instances, right?

Of course, there can be a legitimate use for side effects of the construction of variables of thread local storage duration that are not odr-used (e.g., a thread tracker). However, the advantage for guaranteeing this is not enough to compensate for the aforementioned drawback, so these variables are allowed to be eliminated as long as they aren't odr-used. (Your compiler can choose not to do, though. And you can also make your own wrapper around std::thread that takes care of this.)

There is no problem with your observation. [basic.stc.static]/2 prohibits eliminating variables with static storage duration:

If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].

This restriction is not present for other storage durations. In fact, [basic.stc.thread]/2 says:

A variable with thread storage duration shall be initialized before its first odr-use and, if constructed, shall be destroyed on thread exit.

This suggests that a variable with thread storage duration need not be constructed unless odr-used.

There is no problem with your observation. [basic.stc.static]/2 prohibits eliminating variables with static storage duration:

If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].

This restriction is not present for other storage durations. In fact, [basic.stc.thread]/2 says:

A variable with thread storage duration shall be initialized before its first odr-use and, if constructed, shall be destroyed on thread exit.

This suggests that a variable with thread storage duration need not be constructed unless odr-used.


But why is this discrepancy?

For static storage duration, there is only one instance of a variable per program. The side effects of construction thereof can be significant (kinda like a program-wide constructor), so the side effects are required.

For thread local storage duration, however, there is a problem: an algorithm may start a lot of threads. For most of these threads, the variable is completely irrelevant. It would be hilarious if an external physics simulation library that calls std::reduce(std::execution::par_unseq, first, last) ends up creating a lot of foo instances, right?

Of course, there can be a legitimate use for side effects of the construction of variables of thread local storage duration that are not odr-used (e.g., a thread tracker). However, the advantage for guaranteeing this is not enough to compensate for the aforementioned drawback, so these variables are allowed to be eliminated as long as they aren't odr-used. (Your compiler can choose not to do, though. And you can also make your own wrapper around std::thread that takes care of this.)

Source Link
L. F.
  • 20.9k
  • 9
  • 57
  • 85

There is no problem with your observation. [basic.stc.static]/2 prohibits eliminating variables with static storage duration:

If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].

This restriction is not present for other storage durations. In fact, [basic.stc.thread]/2 says:

A variable with thread storage duration shall be initialized before its first odr-use and, if constructed, shall be destroyed on thread exit.

This suggests that a variable with thread storage duration need not be constructed unless odr-used.