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.
