This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/11108] <iostream> causes transform() to not compile with tolower()
- From: "sebor at roguewave dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 3 Jun 2008 19:16:16 -0000
- Subject: [Bug libstdc++/11108] <iostream> causes transform() to not compile with tolower()
- References: <bug-11108-6231@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #11 from sebor at roguewave dot com 2008-06-03 19:16 -------
(In reply to comment #10)
[...]
> Quick fix from the PDF (in case it goes away again):
> Provide a manual cast for toupper to explicitly declare "which toupper" we
> mean.
>
> std::transform(&s[0], &s[0] + 5, &s[0],
> static_cast<int (*)(int)>(std::toupper));
Unfortunately, this is also incorrect because std::toupper(int) typically
has C linkage while (int (*)(int)) has C++ linkage and pointers to functions
with different language linkages are incompatible. That gcc accepts this
form is due to bug 2316. Other compilers diagnose the cast.
Ironically, using a type with C linkage in the cast isn't guaranteed to be
correct either (where correct is defined as 100% portable) because the C++
standard doesn't specify the linkage of C functions such as toupper(int).
Although it will work with the majority of implementations.
extern "C" typedef int cfun_t (int);
char s [] = "abcd";
std::transform(&s[0], &s[0] + 5, &s[0],
static_cast<cfun_t*>(std::toupper));
The kicker, though, is that extern "C" declarations cannot appear at local
or class scope so the typedef above cannot appear near the call where it's
used but way above the definition of the function where the call is made.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11108