i filled feedback form in the VS with this data and sent it to VS team. 
hope they will fix

вторник, 28 февраля 2017 г., 13:23:34 UTC+2 пользователь Vitaliy Bondarchuk 
написал:
>
> hi Kenton
>
> yes, when you initialize by explicit value (number or literal) - it works 
> better then when you initialize by return value of a function
> look please here:
>
> header.h ==============
> pragma once
>
> namespace test
> {
> typedef unsigned int uint;
> typedef uint BitCount;
>
> template <typename T> inline constexpr T f1() { return T(0x12345678); } 
> constexpr BitCount v1 = f1<BitCount>();
>
> constexpr BitCount v2 = 0x12345678;
>
> inline constexpr unsigned int f3() { return 0x12345678; }
> constexpr BitCount v3 = f3();
>
> constexpr auto v4 = "1234567890qwertyuiopasdfghjklzxcvbnm";
>
> inline constexpr auto f5() { return 
> "1234567890qwertyuiopasdfghjklzxcvbnm"; }
> constexpr auto v5 = f5();
>
> struct S
> {
> char a[4096];
> };
> inline constexpr auto f6() { return S(); }
> constexpr auto v6 = f6();
>
> template <typename T> constexpr T f7 = { 1 };
> constexpr BitCount v7 = f7<BitCount>;
>
> constexpr BitCount v9 = 0x12345678; //address of this is taken in the 
> main()
> }
> ====================================
> ConsoleApplication1.cpp ==================
> #include "stdafx.h"
> #include "Header.h"
> int main()
> {
> auto v10 = &test::v9;
>
> printf("1=%p\n", v10);
>     return 0;
> }
> ====================================
> Source.cpp ==================
> #include "stdafx.h"
> #include "Header.h"
> ====================================
> resulting map:
>
>
> <https://lh3.googleusercontent.com/-pmJCKfJvUkg/WLVcr0774vI/AAAAAAAABrM/snp2E2sBU7AlprKABT0KY5XDOniKiNfiACLcB/s1600/Untitled.jpg>
>
> The compiler from VS version 14.0.25431.01 Update 3
> Map analyzing tool http://www.sikorskiy.net/prj/amap/
> The test project attached :)
>
>
>
>
> понедельник, 27 февраля 2017 г., 23:10:04 UTC+2 пользователь Kenton Varda 
> написал:
>>
>> Oh wow, I didn't realize on my first read that the initialization 
>> expression makes a difference -- if it's just the value `1` rather than 
>> `kj::unit<T>()` then it gets elided properly? That's really strange! Since 
>> it is a constexpr, the compiler really ought to be evaluating and 
>> substituting the expression with the raw value at compile time, so that 
>> they are treated identically. I guess this is another symptom of MSVC's 
>> constexpr support being poor.
>>
>> But I guess this means there's an easy solution: Move the declarations of 
>> BITS, BYTES, etc. up into the #ifdef CAPNP_DEBUG_TYPES right above where 
>> they are declared currently. For the non-debug-types branch, initialize 
>> them all to `1` rather than `kj::unit<T>()`.
>>
>> Happy to accept such a PR.
>>
>> -Kenton
>>
>> On Mon, Feb 27, 2017 at 12:59 PM, Harris Hancock <[email protected]> 
>> wrote:
>>
>>> It does sound like a disappointing MSVC bug. Perhaps C++14 variable 
>>> templates generate better MSVC output? Something like:
>>>
>>> template <typename T> constexpr T unit {1};
>>> constexpr BitCount BITS = unit<BitCount>;
>>>
>>> If so, that could be part of a solution. I'll test when I can.
>>>
>>> Harris
>>>
>>> On Mon, Feb 27, 2017 at 11:36 AM, Kenton Varda <[email protected]> 
>>> wrote:
>>>
>>>> Hi Vitaliy,
>>>>
>>>> Hmm, this seems like a pretty big bug in MSVC. It should be 
>>>> de-duplicating constants across object files, and it should be eliding the 
>>>> ones that aren't used.
>>>>
>>>> Note that these constants are only simple integers if you aren't 
>>>> defining CAPNP_DEBUG_TYPES. If CAPNP_DEBUG_TYPES is defined then these 
>>>> constants have special types that perform unit analysis, and your example 
>>>> code would not compile.
>>>>
>>>> I don't see how we can avoid defining the constants in a release build. 
>>>> They are used all over in the Cap'n Proto implementation. But it's very 
>>>> surprising to me that MSVC can't handle elide simple integer constants.
>>>>
>>>> Harris, do you have any thoughts?
>>>>
>>>> -Kenton
>>>>
>>>> On Mon, Feb 27, 2017 at 3:07 AM, Vitaliy Bondarchuk <
>>>> [email protected]> wrote:
>>>>
>>>>> hi
>>>>>
>>>>> VS2015 (update pack 3) compiler produced own copy of these constants 
>>>>> in each object file:
>>>>> constexpr BitCount BITS = kj::unit<BitCount>();
>>>>> constexpr ByteCount BYTES = kj::unit<ByteCount>();
>>>>> constexpr WordCount WORDS = kj::unit<WordCount>();
>>>>> constexpr ElementCount ELEMENTS = kj::unit<ElementCount>();
>>>>> constexpr WirePointerCount POINTERS = kj::unit<WirePointerCount>();
>>>>>
>>>>> As example map file of resulted binary tell me that I have 22 copies 
>>>>> of capnp::BITS in it. 88 bytes is not a big deal, but... it's a bit 
>>>>> inaccurate )
>>>>> And this happens when the header visible to just 17 my cpp files. And 
>>>>> a cpp file doesn't need even use a constant - include the header enough 
>>>>> for 
>>>>> produce variable in the object file.
>>>>>
>>>>> As I understand you use it for special types in DEBUG build.
>>>>> But can it be a bit more trivial for RELEASE?
>>>>>
>>>>> I tried simple project with the header:
>>>>>
>>>>> namespace kj
>>>>> {
>>>>> template <typename T>
>>>>> inline constexpr T unit() { return T(1); }
>>>>>
>>>>> inline constexpr unsigned int unit3() { return 1; }
>>>>> }
>>>>>
>>>>> namespace capnp
>>>>> {
>>>>> typedef unsigned int uint;
>>>>> typedef uint BitCount;
>>>>>
>>>>> constexpr BitCount BITS1 = kj::unit<BitCount>();
>>>>> constexpr BitCount BITS2 = 1;
>>>>> constexpr BitCount BITS3 = kj::unit3();
>>>>> }
>>>>>  
>>>>> all 3 constants have value 1. and all 3 properly can be used as size 
>>>>> of an array
>>>>> #include "Header.h"
>>>>>
>>>>> void f();
>>>>>
>>>>> int main()
>>>>> {
>>>>> int b1[capnp::BITS1] = {};
>>>>> int b2[capnp::BITS2] = {};
>>>>> int b3[capnp::BITS3] = {};
>>>>> f();
>>>>>
>>>>> printf("1=%d 2=%d 3=%d\n", capnp::BITS1, capnp::BITS2, capnp::BITS3);
>>>>>
>>>>>     return 0;
>>>>> }
>>>>>
>>>>> but the map file is:
>>>>> 3 .bss 62c 4 unsigned int const capnp::BITS1 ConsoleApplication1.obj 
>>>>> ?BITS1@capnp@@3IB
>>>>> 3 .bss 630 4 unsigned int const capnp::BITS3 ConsoleApplication1.obj 
>>>>> ?BITS3@capnp@@3IB
>>>>> 3 .bss 634 4 unsigned int const capnp::BITS1 Source.obj 
>>>>> ?BITS1@capnp@@3IB
>>>>> 3 .bss 638 8 unsigned int const capnp::BITS3 Source.obj 
>>>>> ?BITS1@capnp@@3IB
>>>>>
>>>>>
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "Cap'n Proto" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to [email protected].
>>>>> Visit this group at https://groups.google.com/group/capnproto.
>>>>>
>>>>
>>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Cap'n Proto" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> Visit this group at https://groups.google.com/group/capnproto.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
Visit this group at https://groups.google.com/group/capnproto.

Reply via email to