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ć
signature.asc
Description: PGP signature
