[Bug libstdc++/71108] New: to_string is relatively slow
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71108 Bug ID: 71108 Summary: to_string is relatively slow Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: adrian.wielgosik at gmail dot com Target Milestone: --- Currently to_string is implemented in terms of vsnprintf, which makes it close in performance to the sprintf family. Meanwhile hand-written implementations of to_string can be up to an order of magnitude faster. For example, this function is 3-7x faster than 6.1 std::to_string(unsigned int) in a microbenchmark. std::string to_string(unsigned int value) { char buffer[20]; char *end = std::end(buffer); char *it = end; do { it--; *it = '0' + value % 10; value /= 10; } while (value); return std::string(it, end); }
[Bug c++/68377] [c++17] "binary expression in operand of fold-expression" error when folding an expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68377 Adrian Wielgosik changed: What|Removed |Added CC||adrian.wielgosik at gmail dot com --- Comment #2 from Adrian Wielgosik --- A slghtly simpler code that reproduces it: #include template int f(Tx... xs) { return ((xs+1) + ...); } int main() { std::cout << f(3,4,5) << "\n"; return 0; }
[Bug c++/67565] New: [concepts] Very slow compile time and high memory usage with complex concept definitions, even if unused
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67565 Bug ID: 67565 Summary: [concepts] Very slow compile time and high memory usage with complex concept definitions, even if unused Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adrian.wielgosik at gmail dot com Target Milestone: --- Example: template concept bool Constructible() { return false || requires (T t) { { t.~T() } noexcept; }; } template concept bool Semiregular() { return Constructible() && Constructible() && Constructible() && Constructible() && Constructible() && Constructible() && Constructible(); } template concept bool Sentinel() { return Semiregular() && Semiregular(); } template S> void func(I first, S last) { } int main(){} time ./g++trunk -std=c++1z main.cpp real0m8.855s user0m7.887s sys 0m0.896s It also consumed over 2GB of RAM at peak. Note that the function which checks for concepts wasn't even called, so no actual concept checks were done. Simplifying this case any more, like removing "false ||", fixes the problem. A big chain of "Constructible() &&" may look strange, but it's just a simplified case - originally I tried to rewrite concepts from Eric Niebler's Ranges proposal, which could check the same concept multiple times.
[Bug libstdc++/66059] make_integer_sequence should use a log(N) implementation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66059 Adrian Wielgosik changed: What|Removed |Added CC||adrian.wielgosik at gmail dot com --- Comment #9 from Adrian Wielgosik --- I did a simple comparison of the improved libstdc++ implementation and Daniel's one - the difference in time and resource usage is still significant. $ cat with_stdlib.cpp #include std::make_index_sequence<5000> thing; $ cat with_tao.cpp #include tao::seq::make_index_sequence<5000> thing; $ ./g++trunk with_stdlib.cpp -c -ftime-report Execution times (seconds) phase setup : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 1%) wall 1386 kB ( 1%) ggc phase parsing : 0.97 (100%) usr 0.01 (100%) sys 0.97 (98%) wall 118230 kB (99%) ggc phase finalize : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 1%) wall 0 kB ( 0%) ggc |name lookup: 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 1%) wall 440 kB ( 0%) ggc |overload resolution: 0.03 ( 3%) usr 0.00 ( 0%) sys 0.03 ( 3%) wall 335 kB ( 0%) ggc parser (global) : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 1%) wall 1459 kB ( 1%) ggc parser struct body : 0.02 ( 2%) usr 0.00 ( 0%) sys 0.01 ( 1%) wall 1049 kB ( 1%) ggc parser inl. func. body : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 1%) wall 37 kB ( 0%) ggc template instantiation : 0.95 (98%) usr 0.01 (100%) sys 0.94 (95%) wall 115432 kB (96%) ggc TOTAL : 0.97 0.01 0.99 119627 kB Internal checks disabled; compiler is not suited for release. Configure with --enable-checking=release to enable checks. $ ./g++trunk -I sequences/include/tao/seq/ with_tao.cpp -c -ftime-report Execution times (seconds) phase setup : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 1386 kB (16%) ggc phase parsing : 0.10 (100%) usr 0.01 (100%) sys 0.11 (100%) wall7413 kB (84%) ggc |name lookup: 0.01 (10%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 450 kB ( 5%) ggc preprocessing : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 9%) wall 192 kB ( 2%) ggc parser (global) : 0.01 (10%) usr 0.00 ( 0%) sys 0.01 ( 9%) wall 1483 kB (17%) ggc parser struct body : 0.02 (20%) usr 0.00 ( 0%) sys 0.02 (18%) wall 1063 kB (12%) ggc template instantiation : 0.07 (70%) usr 0.01 (100%) sys 0.07 (64%) wall 4563 kB (52%) ggc TOTAL : 0.10 0.01 0.11 8811 kB Internal checks disabled; compiler is not suited for release. Configure with --enable-checking=release to enable checks.
[Bug c++/68409] Garbage added to a map instead of object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68409 Adrian Wielgosik changed: What|Removed |Added CC||adrian.wielgosik at gmail dot com --- Comment #2 from Adrian Wielgosik --- Your operator< doesn't seem to satisfy strict weak ordering. Once I rewrote it to a basic but safer version: bool operator< (const chave& lhs, const chave& rhs) { if(lhs.numeros_ord != rhs.numeros_ord) return lhs.numeros_ord < rhs.numeros_ord; return lhs.estrelas_ord < rhs.estrelas_ord; } It seems to work fine to me. (Also, when testing with clang/GCC, try using AddressSanitizer or valgrind, you'll have a better chance of catching illegal memory accesses.)
[Bug c++/67178] New: [concepts] ICE on self-referencing concept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67178 Bug ID: 67178 Summary: [concepts] ICE on self-referencing concept Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adrian.wielgosik at gmail dot com Target Milestone: --- Created attachment 36165 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36165&action=edit compiler output template concept bool SomeConcept = requires(SomeConcept val) { { val }; }; void function(SomeConcept) {} int main() { function(1); } Revision 226764. Attached compiler output.
[Bug c++/67318] New: [6 regression] Parsing error when using abbreviated integral type names in template parameter pack declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67318 Bug ID: 67318 Summary: [6 regression] Parsing error when using abbreviated integral type names in template parameter pack declaration Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adrian.wielgosik at gmail dot com Target Milestone: --- The following code: template struct MyStruct; int main(){} Results in an error: main.cpp:16:15: error: expected ‘>’ before ‘...’ token template ^ Happens for: short, long, long long, unsigned, signed, unsigned short... Does not happen for: all the above with "int" appended, int, char, bool.
[Bug c++/72682] New: Redundant concept diagnostics when the same concept is checked multiple times
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72682 Bug ID: 72682 Summary: Redundant concept diagnostics when the same concept is checked multiple times Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adrian.wielgosik at gmail dot com Target Milestone: --- A simple code example: template using id=T; template concept bool A = requires(T a) { a==a; }; template concept bool B = A && // (1) basic usage A && // (2) duplicate concept check A && // (3) different concept check that happens to check the same type A>; // (4) same as above template requires B void f(T){} struct S{} s; int main(){ f(s); } Produces the following diagnostic (first couple of lines that were not relevant were omitted): main.cpp:4:14: note: within ‘template concept const bool A [with T = S]’ concept bool A = requires(T a) { a==a; }; ^ main.cpp:4:14: note: with ‘S a’ main.cpp:4:14: note: the required expression ‘(a == a)’ would be ill-formed main.cpp:4:14: note: within ‘template concept const bool A [with T = S]’ main.cpp:4:14: note: with ‘S a’ main.cpp:4:14: note: the required expression ‘(a == a)’ would be ill-formed main.cpp:4:14: note: within ‘template concept const bool A [with T = S]’ main.cpp:4:14: note: with ‘S a’ main.cpp:4:14: note: the required expression ‘(a == a)’ would be ill-formed main.cpp:4:14: note: within ‘template concept const bool A [with T = S]’ main.cpp:4:14: note: with ‘S a’ main.cpp:4:14: note: the required expression ‘(a == a)’ would be ill-formed Notice that all four checks in the end checked the concept A on the type S and produced the exact same diagnostic. For a real world example: if you use Ranges TS StrictTotallyOrdered on unorderable type, it's going to check StrictTotallyOrdered three times on the same type (and then also check all operators like "{t < u}->Boolean" extra two times, and then a duplicate check of EqualityComparable), which can easily produce over a dozen redundant messages, while ideally the whole diagnostic should contain only six messages, one for each comparison operator.