Bug 104706 - make_unique cannot create struct of size of 0 due to default_delete's static_assert failure
Summary: make_unique cannot create struct of size of 0 due to default_delete's static_...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-02-26 23:58 UTC by qingzhe huang
Modified: 2022-02-28 09:45 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description qingzhe huang 2022-02-26 23:58:41 UTC
See code in compiler explorer: https://www.godbolt.org/z/cb8973Ys1

struct of size of 0 does have its usage and it is supported by GNU C (https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html). However, make_unique makes it impossible to create such an unique_ptr because its default_delete requires "A" must have non-zero size.

struct A{
alignas(int[0]) int ptr[0];
};
void test(){
	unique_ptr<A> ptr=make_unique<A>();
}

 error: static assertion failed: can't delete pointer to incomplete type
   83 |         static_assert(sizeof(_Tp)>0,
      |                       ~~~~~~~~~~~^~


I am not arguing that static_assert is reasonable. My point is that "make_shared" can actually deal this properly. i.e.
shared_ptr ptr=make_shared<A>();
gives no error at all.
Comment 1 Jonathan Wakely 2022-02-28 09:36:22 UTC
(In reply to qingzhe huang from comment #0)
> See code in compiler explorer: https://www.godbolt.org/z/cb8973Ys1

Again, please provide the info requested by https://gcc.gnu.org/bugs (which clearly says not just a URL to somewhere else).

> struct of size of 0 does have its usage and it is supported by GNU C
> (https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html). However, make_unique
> makes it impossible to create such an unique_ptr because its default_delete
> requires "A" must have non-zero size.

Good, this code is useless. I dispute that it has uses, except as part of another struct, or with another member present.

Specifically, if you create this object using make_unique<A>() then there is no additional memory after it, so no way to ever access the array elements (because there aren't any array elements).

I don't think we want to support this.