New issue
Advanced search Search tips

Issue 811266 link

Starred by 2 users

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug

Blocking:
issue 94925
issue 807491



Sign in to add a comment

Global initialization broken in MSVC for many types

Project Member Reported by gab@chromium.org, Feb 12 2018

Issue description

We recently discovered that MSVC generates static initializers for simple types (constexpr default constructor w/ private POD members).

We reverted usage of this pattern for LazyInstance, but it turns out we use this pattern elsewhere already, e.g. for AtomicSequenceNumber and TimeTicks in at least 25 non-test files [1]..!

[1] https://cs.chromium.org/search/?q=namespace%5C+%5C%7B(%5B%5E%7D%5D%7C%5Cn)*%5Cn%5Cw*(base::)?(AtomicSequenceNumber%7CTime(Ticks%7CDelta))(%5B%5E(;%5D%7C%5Cn)*;+pcre:yes+-file:test.cc&sq=package:chromium&type=cs

We discussed on cxx@chromium.org that we shouldn't (at least not yet) use Clang-only, non-spec features [2]... so, what do we do now?!

[2] https://groups.google.com/a/chromium.org/d/topic/cxx/l2hyCD3iZLw/discussion
 

Comment 1 by thakis@chromium.org, Feb 12 2018

Meh, nothing, imho.

Comment 2 by gab@chromium.org, Feb 12 2018

Description: Show this description

Comment 3 by dcheng@chromium.org, Feb 12 2018

IIUC, the issue is initializing non-constexpr variables. I would expect most TimeTicks variables to be constexpr.

This just leaves AtomicSequenceNumber to deal with: using a variant of linker initialized should be straightfoward I would imagine.

thakis: This doesn't necessarily seem like something we should just ignore, unless the official policy of the Chromium project changes to explicitly state that clang is the only supported compiler?

Comment 4 by thakis@chromium.org, Feb 12 2018

Oh, I didn't realize that https://chromium.googlesource.com/chromium/src/+/ad6d8a9bbf9bd5e2%5E%21/#F0 is fairly new, I thought that AtomicSequenceNumber had been around for a long time.

Still, it's been around since last July without known problems, and in a week or two we'll have more data on if the clang switch is going to stick for good, and if it does we may or may not have to do anything, so imho we should wait for that before deciding on doing anything.

I don't have a strong opinion though, so others feel differently, I'll defer to y'all.
If the only effect is that we have a binary size increase on MSVC or something, that's OK.

What makes me uncomfortable is when we have detectable behavior changes that e.g. cause DCHECKs because we were _relying_ on the clang behavior in an important way.  Those are the cases I'd rather not have, not only now, but even if the clang switch sticks.
It's really unfortunate that MSVC isn't doing compiler initialization in cases where it clearly ought to be done. I take it the issue with static initializers was that the order of initialization was a problem?
That's tends to be the thing about optimizations. They're optional and code shouldn't always depend on them being there.

Now if the spec says the optimization is required, that's a different story. However, I haven't found any place that requires a constexpr constructor to be optimized out in the spec.
If it brings you any amusement:

I would hope that no self-respecting compiler would miss the optimization opportunity to do what I originally said: "A constexpr function is evaluated at compile time if all its arguments are constant expressions."

-- Bjarne Stroustrup 

https://isocpp.org/blog/2013/01/when-does-a-constexpr-function-get-evaluated-at-compile-time-stackoverflow#comment_208

Comment 9 by gab@chromium.org, Feb 13 2018

Re. #3, right TimeTicks is usually constexpr, those are fine.

The ones I was referring to are in startup_metric_utils.cc (same regex without AtomicSequenceNumber blended in hihlights those : https://cs.chromium.org/chromium/src/components/startup_metric_utils/browser/startup_metric_utils.cc?type=cs&q=namespace%5C+%5C%7B(%5B%5E%7D%5D%7C%5Cn)*%5Cn%5Cw*(base::)?(Time(Ticks%7CDelta))(%5B%5E(;%5D%7C%5Cn)*;+pcre:yes+-file:test.cc&sq=package:chromium&l=41 ).

They're default initialized to 0, in this case though I'm fairly certain they're only used on the main thread so racy initialization is not an issue.

That leaves AtomicSequenceNumber and others we may not be aware of yet...

Regarding the spec and MSVC not *having* to optimize this: yeah, that's pretty sad...  With clang we can even go a step further and use the [[clang::require_constant_initialization]] attribute. But, as discussed on cxx@, it's not clear we're ready/willing to do this (I'd love it if we could just rely on this sane but non spec'ed property...).

Comment 10 by gab@chromium.org, Feb 23 2018

Blocking: 94925

Sign in to add a comment