Tobias Burnus <[email protected]> writes:

> Arsen Arsenović wrote:
>> ... or such.  (didn't try either snippet, but both should be mostly
>> right.  Maybe even plain 'new' works and we can drop 'gomp_malloc' usage
>> altogether, given that we should be able to link libsupc++; that should
>> throw in case of being out of memory, and, since we have no exceptions,
>> crash, I think?)
>
> I think you don't mean crash but abort. - However, the whole point of
> gomp_malloc is to avoid crashes without diagnostic in the
> failue case. Hence, the current code reads as:

Yes, the diagnostic is not pretty:

  /tmp$ gcc -fno-exceptions -x c++ - <<<'int main() { while (1) new int{}; }' 
-lsupc++
  /tmp$ ulimit -v $((32*1024))
  /tmp$ ./a.out 
  terminate called after throwing an instance of 'St9bad_alloc'
    what():  std::bad_alloc
  Aborted                    (core dumped) ./a.out
  /tmp 134 $ 

... that's why I added two more suggestions (but it is semantically
equivalent, which is why I mention it at all).

> void *
> gomp_malloc (size_t size)
> {
>   void *ret = malloc (size);
>   if (ret == NULL)
>     gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
>   return ret;
> }
>
> * * *
>
> In any case, I think it probably makes most sense to do '(type)' style
> first - being compatible with C and C++ - and once everything is converted,
> we can still think about how to handle it best as cleanup step.

As mentioned, that isn't necessarily compatible with C++, for types that
require some initialization.  Which should, hopefully, be most types, as
we phase in constructors.

Is there a reason C compatibility in the newly-C++ sources is a concern?
I can't think of any.  I can see the need for it in omp{,_lib}.h, but
not the internal sources (or even libgomp*.h)

If not, IMO it's better to avoid needing future churn, given that we can
make the 'new_...' helper (and, on that note, we should probably also
slowly phase in std::unique_ptr but that's not needed in the initial
conversion pass, and it'd make it harder to review, but a helper type
like:


  template<typename T>
  struct gomp_freeer
  {
      /* static */ void operator() (T* t)
      { /*gomp_*/free (static_cast<void *> (t)); }
  };
  
  template<typename T>
  using unique_ptr = std::unique_ptr<T, gomp_freeer<T>>;
  
  template<typename T, typename... Args>
  unique_ptr<T>
  make_unique (Args&&... args)
  { return unique_ptr<T> (new (/*gomp_*/malloc (sizeof (T))) 
T(std::forward<Args>(args)...)); }


... would work).
-- 
Arsen Arsenović

Attachment: signature.asc
Description: PGP signature

Reply via email to