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.
