Bug 30928 - add casts to libc overloads
Summary: add casts to libc overloads
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.3.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-02-22 18:19 UTC by Marc Glisse
Modified: 2010-01-14 20:44 UTC (History)
4 users (show)

See Also:
Host:
Target: sparc-sun-solaris2.8
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-01-30 12:07:28


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marc Glisse 2007-02-22 18:19:52 UTC
Headers like cwchar add overloads to libc functions. Here I am interested in the functions for which the standard C version takes a const pointer and returns a non-const pointer and in C++ this version is replaced by one with const everywhere and one with no const anywhere. For this, in c_std mode, g++ takes the libc version (instead of the full-const version) and adds an overload which looks like:

  inline wchar_t*
  wcschr(wchar_t* __p, wchar_t __c)
  { return wcschr(const_cast<const wchar_t*>(__p), __c); }

The const_cast does not look very useful, but that is not the issue (it makes it easier to understand, which is good). I was wondering whether it would be acceptable to add a const_cast<wchar_t*> to the returned value? For the current uses, it would do nothing. But now if a libc decided to provide the full-const version when called by a c++ compiler, this would make it work.

Is there any real case where it would help? Well if bugs 27340 (trivial) and 30112 get fixed, with the following fixinclude rule, it would be the last thing preventing from being able to set __cplusplus to either 1 or 199711L with no testsuite regression (except for breaking the ABI) on solaris (I only checked with 8). Of course this is only one way to achieve this (not the best one, but it requires very little patching).

I will understand if you say no, I am just hoping for a "why not? It doesn't hurt." (remember that in this bug I am only talking about adding some const_casts, the __cplusplus value is an other issue)

The fixinclude rule, for info (I am not proposing it here, just mentionning it for completeness)
/*
 *  Remove extern "C++" parts of solaris libc
 */
fix = {
    hackname  = solaris_no_extern_cpp;
    mach     = '*-*-solaris*';
    files     = "iso/ctype_iso.h";
    files     = "iso/limits_iso.h";
    files     = "iso/locale_iso.h";
    files     = "iso/math_iso.h";
    files     = "iso/setjmp_iso.h";
    files     = "iso/signal_iso.h";
    files     = "iso/stdarg_iso.h";
    files     = "iso/stddef_iso.h";
    files     = "iso/stdio_iso.h";
    files     = "iso/stdlib_iso.h";
    files     = "iso/string_iso.h";
    files     = "iso/time_iso.h";
    files     = "iso/wchar_iso.h";
    files     = "iso/wctype_iso.h";
    select    = 'extern[ \t]*"C\+\+"';
    shell     = "perl -e 'undef $/;$_=<>;s/extern[ \t]*\"C\\\+\\\+\"[ \t]*{([^{}]*{[^{}]*})*[^{}]*}//gs;print'";
    test_text = 'extern "C++" {void f();}';
};

(this uses perl, which I think has been part of the system for a very long time, because I don't know how to do it with sed. I also don't know if the files field accepts wildcards)
Comment 1 Jakub Jelinek 2009-01-30 11:48:21 UTC
For very recent glibc this has been fixed with
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143773
Comment 2 Paolo Carlini 2009-01-30 12:08:58 UTC
*** Bug 33935 has been marked as a duplicate of this bug. ***
Comment 3 Marc Glisse 2009-01-30 20:38:37 UTC
Hello,

looking at the two last comments, I think we are speaking of slightly different things, although they are related. I was asking for some const_cast of the return value, in case the const version of wcschr (or other) we are forwarding to (from the non-const overload) has the official C++ prototype. In any case, it can't hurt and makes the code a bit cleaner with respect to the intended behaviour. I was then planning to ask glibc to insert a macro in the declaration:
extern MYMACRO void* memchr(const void*,int,size_t); where MYMACRO could be defined as "const" by a C++ implementation, but apparently an even better fix was adopted, cool :-)

The fix mentionned by Jakub is the right way to do things for a well-behaved libc (solaris with __cplusplus>=199711L, or apparently a very recent glibc). Hopefully the same thing will be done for the other headers (cstdlib or cmath for instance), although the interaction with C99/C++0X may require 2 macros instead of just one.

Bug 33935 asks that g++ ship a string.h that is equivalent to cstring when __CORRECT_ISO_CPP_STRING_H_PROTO is not defined. Obviously it is not that easy because standard headers including each other may end up including the wrappers, but now that glibc and its multiply included headers are out of the way it may be easier (or not). Too bad there is no easy way to distinguish libc headers from other headers.

Anyway, I want to thank you both because you did not consider these issues negligible. I'd love to help, I know how to fix most of the bugs I have filed related to solaris headers, but I still haven't managed to get the legal paperwork done (keep changing employers, and the FSF disclaimer is not a paper they have ever signed before).
Comment 4 Paolo Carlini 2010-01-14 17:23:46 UTC
It seems to me extremely unlikely that an implementation decides to provide the full-const version when called by a c++ compiler and nothing else, because C++ does *not* add an overload, *replaces both*. Thus it seems definitely premature.

About the unrelated point at the beginning, the const_cast in wcschr, that is *essential* otherwise how can the forwarding to the *other* overload happen? We can only remove it from the plain char overloads, which forwards to the builtins.
Comment 5 Marc Glisse 2010-01-14 20:35:23 UTC
(In reply to comment #4)
> It seems to me extremely unlikely that an implementation decides to provide the
> full-const version when called by a c++ compiler and nothing else, because C++
> does *not* add an overload, *replaces both*. Thus it seems definitely
> premature.

As mentionned in the original bug report, on solaris, it is quite easy to get this behavior. However, I agree that it is not the right way to do it, and the apparition of macros like __CORRECT_ISO_CPP_WCHAR_H_PROTO seems like a much better way to handle things. In some sense the main interest of this bug is to show one way to get c* headers that don't pollute the global namespace on solaris. But "resolved invalid" is right. #33935 (shouldn't that one be unmerged?) is a better place to track the incomplete resolution of DR456 wrt strchr.

> About the unrelated point at the beginning, the const_cast in wcschr, that is
> *essential* otherwise how can the forwarding to the *other* overload happen?

Er, yes, that's obvious. I have no idea what I was thinking when I wrote that (3 years ago). Maybe just that it is a cast in the direction non-const->const (not that it matters).
Comment 6 Paolo Carlini 2010-01-14 20:44:41 UTC
Yes, I agree, in the light of the resolution of DR456, let's keep open 33935 instead, and clarify in it that non-GNU targets have yet to provide a mechanism similar to the one used in recent glibcs.