This is the mail archive of the gcc@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]

Re: string.h and std_cstring.h


I had a look at our header, and it seems good to me.

What we have is: (using only memchr for the example)

  #ifdef __cplusplus
   #define _Const_return const
  #else
   #define _Const_return
  #endif
  
  __BEGIN_DECLS
  
  _C_STD_BEGIN
  extern _Const_return void *memchr( const void *__s, int __c, size_t __n );
  _C_STD_END
  
  __END_DECLS
  
  #ifdef __cplusplus
  _C_STD_BEGIN
  inline void *memchr(void *_S, int _C, _CSTD size_t _N)
      {   /* call with const first argument */
      union { void *_Out; _Const_return void * _In; } _Result;
      return (_Result._In = _CSTD memchr((const void *)_S, _C, _N)), _Result._Out; }
  _C_STD_END
  #endif
  
  #ifdef _STD_USING
  #ifndef __GCC_BUILTIN
  using std::memchr;
  #endif


So we get both the const and the non-const C++ prototypes, and so all is 
good.  

The issue as I see it after my investigation, is that gcc's headers
assume that these things are going to be macros.  Do either the C or C++
specs specify that these things must be macros?  They say that if they are
undefined they have to still work, which they do in our case also.  I mean
that question sincerely.  I couldn't find anywhere that says they have to
be macros, but that just means I didn't find it.

I grepped for the assumtive comment in libstdc++-v3/include/c_std:

  $ grep "Get rid of those macros defined in" *
  std_cctype.h:// Get rid of those macros defined in <ctype.h> in lieu of real functions.
  std_clocale.h:// Get rid of those macros defined in <locale.h> in lieu of real functions.
  std_cmath.h:// Get rid of those macros defined in <math.h> in lieu of real functions.
  std_csetjmp.h:// Get rid of those macros defined in <setjmp.h> in lieu of real functions.
  std_csignal.h:// Get rid of those macros defined in <signal.h> in lieu of real functions.
  std_cstdio.h:// Get rid of those macros defined in <stdio.h> in lieu of real functions.
  std_cstdlib.h:// Get rid of those macros defined in <stdlib.h> in lieu of real functions.
  std_cstring.h:// Get rid of those macros defined in <string.h> in lieu of real functions.
  std_ctime.h:// Get rid of those macros defined in <time.h> in lieu of real functions.
  std_cwchar.h:// Get rid of those macros defined in <wchar.h> in lieu of real functions.
  std_cwctype.h:// Get rid of those macros defined in <wctype.h> in lieu of real functions.

It seems to me that a proper fix would be to change the above headers 
to do something like:  (memchr and std_cstring.h for the example)

From:

  #undef memchr
  namespace std
  {
    using ::memchr;

    inline void*
    memchr(void* __p, int __c, size_t __n)
    { return memchr(const_cast<const void*>(__p), __c, __n); }
  }

To:

  namespace std
  {
    #ifdef memchr  // Only undef and override if these are macros.
    #undef memchr
    using ::memchr;

    inline void*
    memchr(void* __p, int __c, size_t __n)
    { return memchr(const_cast<const void*>(__p), __c, __n); }
    #endif
  }


That way the macros are only overridden if they are macros, as the 
#ifdef fails for the real functions.

Again, comments and feedback appreciated.

Regards,
GP


> 
> Thanks, Joe.  That could be it.  Our header has something like:
> 
>   #ifdef _cplusplus
>   #define Const_ret const
>   #else
>   #define Const_ret
>   #endif
> ..
> ..
>   extern Const_ret char* strrchr(Const_ret char *, int);
> ..
> ..
> 
> So if I am remembering it right (I'm at home right now), then we get one or 
> the other, but never both.  I am not sure about the inlines, but I will check.
> 
> I will work on it and let you all know.
> 
> Thanks again.
> GP
> 
> Joe Buck <Joe.Buck@synopsys.com> said:
> 
> > 
> > > I am working on the QNX i386-nto support in gcc again.
> > > 
> > > The current stumbling block is that our string.h declares
> > > memchr, strchr, strpbrk, strrchr, and strstr as inline.
> > > ...
> > 
> > > Comments?  Am I missing something?
> > 
> > It sounds like you may be running into trouble because C++ requires
> > overloading for certain functions.  For example, in C, strchr is
> > 
> > char* strrchr(const char *, int);
> > 
> > while in C++ there are two:
> > 
> > const char* strrchr(const char *, int);
> > char* strrchr(char *, int);
> > 
> > So, if your OS provides only a C version of strchr, you still have
> > work to do to get the C++ versions right.
> > 
> > 
> 
> 
> 
> -- 
> 
> 
> 
> 


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