hi Harris np :) by the way - there is one more little complain.
the file c++\src\capnp\common.h has definition: static KJ_CONSTEXPR(const) Void VOID = Void(); 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. вторник, 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] <javascript:>> 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.
