On Tue, Feb 28, 2017 at 11:15 AM, Vitaliy Bondarchuk <
[email protected]> wrote:

> [...]
> macro VOID is popular when coding for Windows
> I had workaround this issue with the piece of code:
> #ifdef VOID
> #undef VOID
> #endif
> before I include capnp headers
>
> but generally such things are a bit painful.
>

Vitaliy, I agree, it's painful, and something likely to hit Windows
developers frequently. I would note that Cap'n Proto has an open issue
tracking this problem (https://github.com/sandstorm-io/capnproto/issues/284),
but no great solution yet.

Harris


> вторник, 28 февраля 2017 г., 20:53:54 UTC+2 пользователь Harris Hancock
> написал:
>>
>> Vitaliy, thank you for investigating that, and for reporting it to
>> Microsoft! In the meantime, we can implement the simple workaround Kenton
>> described. I will do so later this week, unless you beat me to it. :)
>>
>> On Tue, Feb 28, 2017 at 4:10 AM, Vitaliy Bondarchuk <
>> [email protected]> wrote:
>>
>>> 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.
>

-- 
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