News:

As usual while waiting for the next release - don't forget to check the nightly builds in the forum.

Main Menu

CC: does not list "allocate", a member function of std::allocator.

Started by edison, September 03, 2014, 05:54:27 PM

Previous topic - Next topic

edison

As the screenshots show, the allocate() of alloc is missing here:

edison

I did try with the ClangLib. It works, the allocate member function is list up:

but ClangLib is slow and not stable...:(

here is a test example with source code: http://en.cppreference.com/w/cpp/memory/allocator

ollydbg

Hi, edison, as you may already see that parsing C++ is not a very simple job, our buildin parser in C::B has many issues here and there especially handling templates, as you reported, this is a bug, but solving those issue are not quite easy as I can see. Unless you use some compiler's help (such as clang or maybe GCC).


If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

ollydbg

BTW: can you make a minimal sample code, so that I can test this bug in my computer? Thanks.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

edison

#include <memory>

int main()
{
    std::allocator<int> a1; // default allocator for ints
    // int * a = a1.allocate(10); // space for 10 ints

    int * a = a1. //<--- here is the bug happened.

    return 0;
}

ollydbg

Quote from: edison on September 04, 2014, 04:06:14 PM
#include <memory>

int main()
{
    std::allocator<int> a1; // default allocator for ints
    // int * a = a1.allocate(10); // space for 10 ints

    int * a = a1. //<--- here is the bug happened.

    return 0;
}


OK, I see the reason. (tested under MinGW 4.7.x compiler)

1, I see that std::allocator class is correctly located in
mingw-builds\473\mingw32\lib\gcc\i686-w64-mingw32\4.7.3\include\c++\bits\allocator.h around line 84

  /**
   * @brief  The @a standard allocator, as per [20.4].
   *
   *  See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html
   *  for further details.
   */
  template<typename _Tp>
    class allocator: public __glibcxx_base_allocator<_Tp>
    {
   public:
      typedef size_t     size_type;
      typedef ptrdiff_t  difference_type;
      typedef _Tp*       pointer;
      typedef const _Tp* const_pointer;
      typedef _Tp&       reference;
      typedef const _Tp& const_reference;
      typedef _Tp        value_type;

      template<typename _Tp1>
        struct rebind
        { typedef allocator<_Tp1> other; };

      allocator() throw() { }

      allocator(const allocator& __a) throw()
      : __glibcxx_base_allocator<_Tp>(__a) { }

      template<typename _Tp1>
        allocator(const allocator<_Tp1>&) throw() { }

      ~allocator() throw() { }

      // Inherit everything else.
    };



Look, there is not member named "allocate", so it should be in its base class. But when I hover the "__glibcxx_base_allocator", I can't see the declaration...

In mingw-builds\473\mingw32\lib\gcc\i686-w64-mingw32\4.7.3\include\c++\i686-w64-mingw32\bits\c++allocator.h
I see

#ifndef _GLIBCXX_CXX_ALLOCATOR_H
#define _GLIBCXX_CXX_ALLOCATOR_H 1

// Define new_allocator as the base class to std::allocator.
#include <ext/new_allocator.h>
#define __glibcxx_base_allocator  __gnu_cxx::new_allocator

#endif


and in mingw-builds\473\mingw32\lib\gcc\i686-w64-mingw32\4.7.3\include\c++\ext\new_allocator.h
I see

  template<typename _Tp>
    class new_allocator
    {
    public:
      typedef size_t     size_type;
      typedef ptrdiff_t  difference_type;
      typedef _Tp*       pointer;
      typedef const _Tp* const_pointer;
      typedef _Tp&       reference;
      typedef const _Tp& const_reference;
      typedef _Tp        value_type;

      template<typename _Tp1>
        struct rebind
        { typedef new_allocator<_Tp1> other; };

      new_allocator() _GLIBCXX_USE_NOEXCEPT { }

      new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }

      template<typename _Tp1>
        new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }

      ~new_allocator() _GLIBCXX_USE_NOEXCEPT { }

      pointer
      address(reference __x) const _GLIBCXX_NOEXCEPT
      { return std::__addressof(__x); }

      const_pointer
      address(const_reference __x) const _GLIBCXX_NOEXCEPT
      { return std::__addressof(__x); }

      // NB: __n is permitted to be 0.  The C++ standard says nothing
      // about what the return value is when __n == 0.
      pointer
      allocate(size_type __n, const void* = 0)
      {
if (__n > this->max_size())
  std::__throw_bad_alloc();

return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      }


See the last function, it is there.

But I'm still not sure how to fix this bug in our CC's code.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

ollydbg

Oh, it looks like it works OK here, see the screen shot.



I just close and reopen the project.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

edison

I am using mingw-w64 4.2 i686 dw2 (gcc 4.9.1) and codeblocks svn 9904, close then re-open project does not help here.
I will try the CB 13.12 w/tdm-gcc 4.7.1 latter.

ollydbg

Quote from: edison on September 04, 2014, 04:50:31 PM
I am using mingw-w64 4.2 i686 dw2 (gcc 4.9.1) and codeblocks svn 9904, close then re-open project does not help here.
I will try the CB 13.12 w/tdm-gcc 4.7.1 latter.
My testing environment is latest C::B trunk and mingw-build 4.7.3.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Jenna

Works out of the box with C::B 9884 and "g++ (GCC) 4.8.3 20140624 (Red Hat 4.8.3-1)" 64Bit on Fedora 20.

edison

There is not change here when using CB 13.12 and TDM-GCC 4.7.1.

I will try SVN 9906 + TDM-GCC 4.8.1 latter.

edison

I think I have found out what cause this problem

when I use the fresh built SVN 9906, all works fine.

but when I trans the old GCC compiler to the new CB default.conf, the problem appear again.

here is the old .conf which seems cause this problem.

edison

When I enable the -std=c++11 in Compiler settings, then close the project and re-open the project, the problem appear again. @_@

update:
I had did some double check test, now I can confirm when enabled the -std=c++11(and -std=gnu++11 ) setting (in project's build option or cb's compiler settings ) will cause "allocate()" of allocator not show in the list.

why the gcc compiler switch affect the CC @_@ It's strange...

Jenna

Quote from: edison on September 04, 2014, 07:35:59 PM
When I enable the -std=c++11 in Compiler settings, then close the project and re-open the project, the problem appear again. @_@

update:
I had did some double check test, now I can confirm when enabled the -std=c++11(and -std=gnu++11 ) setting (in project's build option or cb's compiler settings ) will cause "allocate()" of allocator not show in the list.

Still works here, egally where I add the flags (in project or globally).

edison

Quote from: jens on September 04, 2014, 08:31:36 PM
Still works here, egally where I add the flags (in project or globally).

When I set the flag, close CB and re-run CB, then open the project, the allocate() of CC does not work.

My Ubuntu had something wrong, I will try it latter.

update:
When my project use Clang as compiler, the allocate() CC works even -std=c++11 option was checked.