MSVC
MSVC
Posted Mar 6, 2013 12:22 UTC (Wed) by jwakely (subscriber, #60262)In reply to: MSVC by Cyberax
Parent article: Michaelsen: One
You still don't know what you're talking about. I don't care about user-defined literals but constexpr is very important. Do you consider solving the static initialization order fiasco to be unimportant?
A constexpr constructor ensures a global object is guaranteed to be initialized during the static initialization phase, i.e. before any code starts running, so code that runs before main() can be guaranteed the object will be valid, even across different translation units where the order of initialization is not defined. This is useful e.g. for a global std::mutex that is accessed by different translation units. That doesn't work with MSVC because its std::mutex is not only non-constexpr but it allocates memory in its default constructor.
> Ditto for constexprs - they can already be optimized by the compiler and you'd be hard-pressed to do anything complex in 512 level recursion limit. I've only seen constepxrs in practice used for template brainfskery magic.
There is no problem with instantiation depth, not even any templates involved. "Can be optimized by the compiler" is not the same as "guaranteed to be optimized by the compiler" ... but you need a decent C++11 compiler to actually get that guarantee of course.
Posted Mar 6, 2013 17:39 UTC (Wed)
by Cyberax (✭ supporter ✭, #52523)
[Link] (24 responses)
> That doesn't work with MSVC because its std::mutex is not only non-constexpr but it allocates memory in its default constructor.
>There is no problem with instantiation depth, not even any templates involved.
>"Can be optimized by the compiler" is not the same as "guaranteed to be optimized by the compiler" ... but you need a decent C++11 compiler to actually get that guarantee of course.
Posted Mar 6, 2013 23:03 UTC (Wed)
by nix (subscriber, #2304)
[Link] (5 responses)
Um... even if it's *not* evaluated at compile-time, it is still guaranteed to be evaluated before the static initialization phase. Thus you can use them to construct things that are used *during* the static initialization phase.
Now maybe you don't care about the static initialization phase, but claiming that lack of support for a feature that makes that phase useful is insignificant merely because *you* don't use it is myopic.
Posted Mar 7, 2013 21:13 UTC (Thu)
by jwakely (subscriber, #60262)
[Link] (4 responses)
This is entirely typical for Cyberax. "I can't make Linux work on the desktop, therefore it's impossible, even though other people are telling me they've done it", "The compiler I claim is top-notch doesn't support a feature and I don't care about it, therefore it's unimportant, even though other people have said how it's important to them."
*plonk*
Posted Mar 8, 2013 19:50 UTC (Fri)
by Cyberax (✭ supporter ✭, #52523)
[Link] (3 responses)
>The compiler I claim is top-notch doesn't support a feature and I don't care about it, therefore it's unimportant, even though other people have said how it's important to them.
Does gcc support C# interoperability, for example? It's a very real-world feature necessary for a lot of projects.
Or maybe "#pragma pack" to get a more fitting example?
Posted Mar 8, 2013 21:29 UTC (Fri)
by mpr22 (subscriber, #60784)
[Link] (2 responses)
Posted Mar 8, 2013 21:58 UTC (Fri)
by nix (subscriber, #2304)
[Link] (1 responses)
Posted Mar 8, 2013 23:11 UTC (Fri)
by Cyberax (✭ supporter ✭, #52523)
[Link]
Posted Mar 7, 2013 21:11 UTC (Thu)
by jwakely (subscriber, #60262)
[Link] (17 responses)
The example I was talking about has *no recursion*, so there is no problem with a limit of 512 levels. Why are you even mentioning it?
Posted Mar 8, 2013 19:49 UTC (Fri)
by Cyberax (✭ supporter ✭, #52523)
[Link] (16 responses)
You CAN'T use constexprs to solve the initialization ordering problem. By definition constexprs can't have any side effects (in fact, allowing side effects is a compiler bug). This means that constexprs can refer to each other and can have any ordering.
So using constexprs to allocate a mutex is right out. The only remaining usages:
Basically, that's it.
Posted Mar 10, 2013 19:16 UTC (Sun)
by jwakely (subscriber, #60262)
[Link] (15 responses)
> By definition constexprs can't have any side effects (in fact, allowing side effects is a compiler bug).
Citation needed.
I'll start you off with 7.1.5 [dcl.constexpr] which says "The definition of a constexpr constructor shall satisfy the following constraints: [...] every non-variant non-static data member and base class sub-object shall be initialized"
Please show where in the standard it contradicts that or how to initialize non-static data members without side-effects.
> So using constexprs to allocate a mutex is right out
On a grown-up OS mutexes don't need "allocating" so can be constexpr.
If you disagree please file a defect with the C++ standard, file a GCC bug (category "doing impossible things before breakfast") and tell MS to stop working on the fix to not allocate memory in std::mutex because it's an impossible task, so sayeth Cyberax the unknowing.
I don't think you know what a constexpr constructor is or how it works. Stop trying to educate me on C++, you're embarassing yourself.
Posted Mar 10, 2013 20:55 UTC (Sun)
by Cyberax (✭ supporter ✭, #52523)
[Link] (14 responses)
But OK. Stanza 7.1.5.5:
Given that a function can only involve operations on literals (or references to them) or other constexpr values we are immediately (7.1.5.3) limited in possibilities to refer to non-constexpr data like file handles, for example (because open/close do not return constexprs).
Can a body of a constexpr function involve side effects? No. See 5.19.1 - it explicitly notes:
Then in the stanza 5.19.2 the Standard lists tons of things that are Verbotten. Included in them:
Basically, constepxrs can only use other constexprs (in evaluated paths). And the only available constexpr functions are simple mathematical functions that can't produce side-effects.
>On a grown-up OS mutexes don't need "allocating" so can be constexpr.
> I don't think you know what a constexpr constructor is or how it works. Stop trying to educate me on C++, you're embarassing yourself.
Posted Mar 10, 2013 23:19 UTC (Sun)
by jwakely (subscriber, #60262)
[Link] (13 responses)
A constexpr constructor is the language feature that guarantees objects with non-trivial constructors (such as std::mutex) can be initialized during the static initialization phase. Without a constexpr constructor you have no such guarantee. A constexpr constructor can set a global object's member variables, those member variables are state, setting them to one value or another is observable to the rest of the program. If that state has not been initialized before it's needed, you have a problem. A constexpr constructor ensures it is set before needed.
Posted Mar 11, 2013 4:14 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link] (12 responses)
Let me quote:
> You still don't know what you're talking about. I don't care about user-defined literals but constexpr is very important. Do you consider solving the static initialization order fiasco to be unimportant?
> A constexpr constructor can set a global object's member variables, those member variables are state, setting them to one value or another is observable to the rest of the program.
In fact, constexprs are designed in such way that they make a purely functional language. So they can be evaluated in any order and at any time. You can ALWAYS replace them with static initialization, only you might have to do evaluation manually.
Posted Mar 11, 2013 10:19 UTC (Mon)
by jwakely (subscriber, #60262)
[Link] (7 responses)
Posted Mar 11, 2013 10:32 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link] (6 responses)
No, constexprs do not have side effects since they don't modify anything outside of their scope. No, constexpr constructors also do not have side effects.
Anyway, my other points still stand:
Posted Mar 11, 2013 11:46 UTC (Mon)
by jwakely (subscriber, #60262)
[Link] (5 responses)
Posted Mar 11, 2013 14:08 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link] (2 responses)
std::mutex has a constexpr constructor (added to maintain compatibility with POSIX), but recursive and timed mutexes don't (check it). MSVC choose to ignore it completely because it's not practical to implement mutexes this way on Windows.
This requirement was just a codification of existing practice where POSIX mutexes can be statically initialized. And yet again, I repeat that constexprs can't solve the problems with initialization order. If your code works with constexprs then it works on MSVC.
Posted Mar 12, 2013 11:52 UTC (Tue)
by jwakely (subscriber, #60262)
[Link] (1 responses)
Things don't get added to the C++ standard for POSIX compatibility if they don't work on other platforms, MS have representatives on the committee so they don't need to "choose to ignore" requirements in the standard, they can prevent them being standardised in the first place. That's how the process is supposed to work, a "top-notch compiler" team doesn't keep quiet then be forced to ship a non-conforming implementation. Having a constexpr constructor is by design, not a compatibility feature, remember that when MSVC eventually fix their std::mutex.
https://connect.microsoft.com/VisualStudio/feedback/detai...
Posted Mar 12, 2013 14:40 UTC (Tue)
by Cyberax (✭ supporter ✭, #52523)
[Link]
>Having a constexpr constructor is by design, not a compatibility feature, remember that when MSVC eventually fix their std::mutex.
Windows synchronization primitives require initialization, so if you want to do a constexpr then you have to use a spinlock to protect a delayed initialization of the real synchronization primitive. Possible, but ugh.
BTW, your very link tells us that the next MSVC version supports constexprs.
Posted Mar 11, 2013 14:23 UTC (Mon)
by nye (subscriber, #51576)
[Link] (1 responses)
But that was a part of the argument that you loudly jumped into before almost immediately throwing insults about.
I think Cyberax must have a great deal of patience to be bothering with you, given your abusive behaviour in this thread.
Posted Mar 12, 2013 12:14 UTC (Tue)
by jwakely (subscriber, #60262)
[Link]
Posted Mar 11, 2013 15:21 UTC (Mon)
by nix (subscriber, #2304)
[Link] (3 responses)
Posted Mar 11, 2013 15:24 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link] (2 responses)
Almost all more-or-less complex algorithms require something that is not really possible with constexprs.
Posted Mar 11, 2013 16:52 UTC (Mon)
by etienne (guest, #25256)
[Link] (1 responses)
If you have a very long list of parameters with plenty of sub-parameters (kind of 4096 channels with 50+ configuration options and their SNMP descriptors), you can have them pre-organised (with their next/previous fields pre-initialised) if you declare them "static" and not malloced.
Note that you could try to support malloc/free inside constexprs by having another section in your ELF file (like .data but after .bss), so that the malloc/free functions (either in glibc or your own wrapper) do not start empty but call brk()/sbrk() to increase that new section... should work at least on Linux (excluding LD_PRELOAD of another malloc/free library).
Posted Mar 11, 2013 17:29 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link]
> Or if you have a long dictionary.
>Note that you could try to support malloc/free inside constexprs by having another section in your ELF file (like .data but after .bss), so that the malloc/free functions (either in glibc or your own wrapper) do not start empty but call brk()/sbrk() to increase that new section
MSVC
Yep, and that's exactly why.
Standard guarantees only 512 level recursion. Everything else is implementation-specific.
So don't use it for anything important.
MSVC
MSVC
MSVC
Wrong. I _can_ make Linux work on desktop. I can't make it work every time with minimal maintenance for most of real world users out there.
Yep, especially if it's such a minor feature.
GCC has a "pack" pragma, though it doesn't support the identifier feature of the Microsoft one.
MSVC
MSVC
MSVC
MSVC
> Standard guarantees only 512 level recursion. Everything else is implementation-specific.
MSVC
1) Precalculating complex mathematics formulae. It's right out - you can't really do anything real-world interesting in 512 level recursion limit.
2) Template mindfskery - instead of using partial template specialization. That cleans up code somewhat, but it still doesn't change the fsked up nature of template metaprogramming.
MSVC
MSVC
I thought it was obvious to anyone who follows C++ development.
>For a constexpr function, if no function argument values exist such that the function invocation substi- tution would produce a constant expression (5.19), the program is ill-formed; no diagnostic required. For a constexpr constructor, if no argument values exist such that after function invocation substitution, ev- ery constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required.
>[Note: Constant expressions can be evaluated during translation. — end note ]
>- a new-expression (5.3.4);
>- a delete-expression (5.3.5);
And you also can't use malloc since it's not a constexpr. So yes, dynamic allocation is impossible.
Then there's no problem with their initialization order. What's the problem that constexprs should be solving?
Yes, please do.
MSVC
MSVC
Certain people in this thread do.
> constexpr is good for compile-time calculations, so the application starts faster;
Which implies that it's possible to do something more complex other than trivial math in constexprs.
Constexprs don't solve static init order problems _AT_ _ALL_. In particular, constexprs can't work with forward declarations.
No it cannot. You can _create_ a constexpr member variable, but you can't _mutate_ it within a constexpr (stanza 5.19.2, "— an assignment or a compound assignment").
MSVC
MSVC
http://en.wikipedia.org/wiki/Side_effect_%28computer_scie...
1) Constexprs are useless for reducing the startup speed.
2) Constexprs do not solve the static init order problem.
MSVC
2) Then why do std::mutex, std::atomic and std::once_flag have constexpr constructors? What's that for?
MSVC
MSVC
MSVC
The standard committee can choose to ignore Microsoft's objections (that happens, really).
No they haven't (yet). Empty std::mutex in MSVC 11 is NOT a constexpr since it uses an extern function in its constructor.
MSVC
MSVC
MSVC
MSVC
MSVC
Or if you have a long dictionary.
MSVC
Not really. You'll be able to initialize the 'prev' pointers. But you can do this just fine with the current static init.
Compile-time? I doubt it. Though you probably could with lots of template magic.
No you can't. Standard explicitly forbids any pointer math that might result in addresses outside of _initialized_ static storage.
