This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/11108] <iostream> causes transform() to not compile with tolower()



------- 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]