This simple test: ---%<--- #include <string> std::string test(int i) { std::string t; std::string s = "("; t = ""; for (int r = i; r; r>>=1) { if (r & 1) t = "1" + t; else t = "0" + t; } s += t; s += ")"; return s; } int main(int argc, char *argv[]) { std::string s = test(16); return 0; } ---%<--- fails to link if compiled with -fno-implicit-templates I believe it is a bug because, it did work before (the above is a reduced test case), and if using a temporary, or explicitly cast it works, e.g.: - t = "1" + t; + t = std::string("1") + t;
The operator+ overloads for the new std::string are present but are not being exported from the library, I'll fix it upstream.
What was the testcase reduced from? The code has never been guaranteed to work, and is completely non-portable, but did happen to work with older versions of GCC.
It is in the Singular package. The patch I plan to use is: ---8<--- diff -up Singular-3-1-6/Singular/Minor.cc.orig Singular-3-1-6/Singular/Minor.cc --- Singular-3-1-6/Singular/Minor.cc.orig 2015-03-28 20:41:36.396539843 -0300 +++ Singular-3-1-6/Singular/Minor.cc 2015-03-28 20:42:33.458542028 -0300 @@ -799,7 +802,7 @@ string MinorKey::toString() const z = this->getRowKey(r); while (z != 0) { - if ((z % 2) != 0) t = "1" + t; else t = "0" + t; + if ((z % 2) != 0) t = string("1") + t; else t = string("0") + t; z = z / 2; } if (r < this->getNumberOfRowBlocks() - 1) @@ -813,7 +816,7 @@ string MinorKey::toString() const z = this->getColumnKey(c); while (z != 0) { - if ((z % 2) != 0) t = "1" + t; else t = "0" + t; + if ((z % 2) != 0) t = string("1") + t; else t = string("0") + t; z = z / 2; } if (c < this->getNumberOfColumnBlocks() - 1) ---8<--- In master branch this function was even commented out: https://github.com/Singular/Sources/blob/master/Singular/Minor.cc#L793 One of the README files still say need to use -fno-implicit-templates: https://github.com/Singular/Sources/blob/master/factory/README#L358
(In reply to Paulo Andrade from comment #3) > - if ((z % 2) != 0) t = "1" + t; else t = "0" + t; > + if ((z % 2) != 0) t = string("1") + t; else t = string("0") + t; I would do simply t.insert(t.begin(), (z % 2) ? '1' : '0'); (Even that is still horribly inefficient, resulting in lots of bytes being shuffled around every time a new character is inserted at the beginning). > One of the README files still say need to use -fno-implicit-templates: > https://github.com/Singular/Sources/blob/master/factory/README#L358 That claim about "the most reliable way" is about 10 years out of date, but if the code is using -fno-implicit-templates then it should be explicitly instantiating the operator+ template in ftmpl_inst.cc instead of relying on undocumented instantiations in libstdc++.so. They shouldn't insist on doing their own manual instantations and then fail to actually instantiate them! This seems like a bug in the package, and your patch just hides it.
This is now fixed in upstream GCC by https://gcc.gnu.org/r221775
This bug can be closed, in the worst case, a simple patch was already applied, and with time upstream will work on it as well.