Stream: general

Topic: heap-allocation in const fn


gnzlbg (Feb 27 2019 at 10:58, on Zulip):

@RalfJ the constinit proposal states that iff the initializer would need to execute at run-time, the program is ill-formed

gnzlbg (Feb 27 2019 at 10:59, on Zulip):

so maybe if you try to do that in C++ you just get a compilation error in the particular cases in which initializing a static variable from a constant-expression would need to heap-allocate.

gnzlbg (Feb 27 2019 at 11:00, on Zulip):

feels a bit brittle, but the proposals do not talk about each other yet - I've asked in the future_proposal channel of the C++ slack about it and pinged both authors

RalfJ (Feb 27 2019 at 11:07, on Zulip):

kk

RalfJ (Feb 27 2019 at 11:08, on Zulip):

constinit seems closest to Rust's const

RalfJ (Feb 27 2019 at 11:08, on Zulip):

I wonder if maybe it should have been more like constexpr, but I am not sure if that would actually help much here

RalfJ (Feb 27 2019 at 11:09, on Zulip):

(Cc @oli @Nicole Mazzuca )

gnzlbg (Feb 27 2019 at 11:20, on Zulip):

honestly the more i look into it, the more I think those who want constinit should just use constexpr

gnzlbg (Feb 27 2019 at 11:21, on Zulip):
constexpr auto foo = maybe_allocates();
constinit static auto bar = foo; // OK unless foo allocated at compile-time

seems brittle.

gnzlbg (Feb 27 2019 at 12:47, on Zulip):

@RalfJ reading some of the minutes from the last C++ meeting, it seems that they just banned non-transient allocations

RalfJ (Feb 27 2019 at 14:06, on Zulip):

@gnzlbg from constinit, or entirely?

gnzlbg (Feb 27 2019 at 14:06, on Zulip):

entirely

gnzlbg (Feb 27 2019 at 14:07, on Zulip):

allocations cannot escape constexpr functions, e.g., you can return an empty vector or string from a constexpr function, but not one that refers to some memory during constant-evaluation (at run-time it would work)

RalfJ (Feb 27 2019 at 14:09, on Zulip):

oh, so that would mean the paper @Nicole Mazzuca referenced is obsolete?

RalfJ (Feb 27 2019 at 14:09, on Zulip):

could you post a link to that in the issue?

gnzlbg (Feb 27 2019 at 14:32, on Zulip):

there is no link

gnzlbg (Feb 27 2019 at 14:33, on Zulip):

the meeting was this week, that was agreed there
there might be an updated paper in the post-meeting mailing , but those are not out yet

gnzlbg (Feb 27 2019 at 14:34, on Zulip):

if non-transient allocations are allowed (in C++23), initializing a constinit from a constant-expression that refers to them would just be ill-formed

RalfJ (Feb 27 2019 at 14:34, on Zulip):

there is no link

wait where did you get the minutes then?

Nicole Mazzuca (Feb 27 2019 at 15:39, on Zulip):

constinit is useful so that you never get static initialization order fiasco

Nicole Mazzuca (Feb 27 2019 at 15:40, on Zulip):

Rust doesn't have this problem, because it's statics are always initialized at compile time

Nicole Mazzuca (Feb 27 2019 at 15:40, on Zulip):

but C++'s statics can be initialized at runtime

nagisa (Feb 27 2019 at 15:44, on Zulip):

@Nicole Mazzuca doesn’t constexpr already guarantee that?

nagisa (Feb 27 2019 at 15:45, on Zulip):

constexpr T myglobal { ... } is what I used.

nagisa (Feb 27 2019 at 15:45, on Zulip):

I guess that makes myglobal const.

Nicole Mazzuca (Feb 27 2019 at 16:01, on Zulip):

yeah

Nicole Mazzuca (Feb 27 2019 at 16:02, on Zulip):

you can't have non-const constexpr variables

Jake Goulding (Feb 27 2019 at 16:41, on Zulip):

wait where did you get the minutes then?

Obviously gnzlbg has bugged the standards meeting.

gnzlbg (Feb 27 2019 at 17:42, on Zulip):

@Nicole Mazzuca Rust does not have C++ static, Rust statics are C++ constinit

Nicole Mazzuca (Feb 27 2019 at 17:42, on Zulip):

yes

Nicole Mazzuca (Feb 27 2019 at 17:42, on Zulip):

that is what I said

gnzlbg (Feb 27 2019 at 18:13, on Zulip):

i think it would be fine to just fail when trying to initialize a Rust variable with a const fn that allows allocations to escape

Nicole Mazzuca (Feb 27 2019 at 18:14, on Zulip):

@gnzlbg https://www.reddit.com/r/cpp/comments/au0c4x/201902_kona_iso_c_committee_trip_report_c20/ makes it seem like http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0784r5.html was accepted

Nicole Mazzuca (Feb 27 2019 at 18:14, on Zulip):

it wasn't yet merged but that's editorial

gnzlbg (Feb 27 2019 at 18:15, on Zulip):

it was accepted with modifications, in particular, non-transient allocations were removed

gnzlbg (Feb 27 2019 at 18:16, on Zulip):

"Allow constexpr allocation, but disallow allocations that are not deleted at compile time." I think that's what they mean by "disallow allocations not deleted at compile-time"

Nicole Mazzuca (Feb 27 2019 at 18:16, on Zulip):

ah, okay

gnzlbg (Feb 27 2019 at 18:16, on Zulip):

the reason was "there is not enough time"

Nicole Mazzuca (Feb 27 2019 at 18:16, on Zulip):

well, I still think it's a useful thing to pay attention to, since I'm fairly certain that it will be added in 23, then

gnzlbg (Feb 27 2019 at 18:17, on Zulip):

maybe they try to propose a good solution for the next meeting

gnzlbg (Feb 27 2019 at 18:17, on Zulip):

but they might do in a separate paper, to not block that one

gnzlbg (Feb 27 2019 at 18:17, on Zulip):

it seems that this meeting was the first time that this paper was really reviewed, and that a lot of people had problems trying to understand what the problem actually was

gnzlbg (Feb 27 2019 at 18:18, on Zulip):

I'm not sure I understand all the problems discussed, but I think this is the crux of it:

constexpr std::vector<std::unique_ptr<int>> v = foo();
int main() { *v[0].get(0) = 42; }
gnzlbg (Feb 27 2019 at 18:19, on Zulip):

(note: if you replace constexpr with const this compiles and works fine in C++ today)

Nicole Mazzuca (Feb 27 2019 at 18:23, on Zulip):

mmh

Nicole Mazzuca (Feb 27 2019 at 18:23, on Zulip):

isn't that the point of mark_immutable_in_constexpr?

Nicole Mazzuca (Feb 27 2019 at 18:23, on Zulip):

so that you can mark, say, vector's buffer as immutable, but not unique_ptrs

gnzlbg (Feb 27 2019 at 22:52, on Zulip):

if the unique_ptrs landed there, they must be pointing to immutable memory as well, right?
so one would somehow need to also mark the memory of the unique_ptr as immutable

gnzlbg (Feb 27 2019 at 22:54, on Zulip):

also, the example above should error at compile-time, but for that you need to prove that the code modifies immutable memory at compile-time

gnzlbg (Feb 27 2019 at 22:57, on Zulip):

that's not easy because *v.get(0) = 42 is "ok" because const is shallow: the pointers in the vector are const, but the memory that they refer to does not get the const propagated to it in the type system

gnzlbg (Feb 27 2019 at 22:58, on Zulip):

so AFAICT one would need to insert run-time checks for this, as in *v.get(0) = 42 could try to modify read-only memory if it were to get executed

Nicole Mazzuca (Feb 28 2019 at 16:03, on Zulip):

no, because you can also put stuff into rwmem

gnzlbg (Feb 28 2019 at 16:43, on Zulip):

@Nicole Mazzuca but you can't free static rwmem

gnzlbg (Feb 28 2019 at 16:45, on Zulip):

so if you have a constexpr vector<unique_ptr<string>> v = ...;, where the string and its contents are in read-write memory, you could write *v.get(0) = to_string('on the heap"); , which would destroy the string in rw memory, and create a new one, whose content is now in the heap

gnzlbg (Feb 28 2019 at 16:46, on Zulip):

the problem there is destroying the string, whose pointer points to the rw memory

gnzlbg (Feb 28 2019 at 16:46, on Zulip):

if the destructor tries to free the memory, the behavior is undefined

gnzlbg (Feb 28 2019 at 16:47, on Zulip):

so the destructor needs a way to tell, whether the memory should be freed or not

gnzlbg (Feb 28 2019 at 16:48, on Zulip):

that's arguably a useful thing to allow, but at the same time every destructor now needs to do this

gnzlbg (Feb 28 2019 at 16:49, on Zulip):

also, run-time code needs to be able to perform this check (given a pointer and a length, is that memory region completely or partially in rw static memory?), so now all code pays for this check

Nicole Mazzuca (Feb 28 2019 at 16:56, on Zulip):

mmmmh

Nicole Mazzuca (Feb 28 2019 at 16:56, on Zulip):

okay

Nicole Mazzuca (Feb 28 2019 at 16:56, on Zulip):

yeah I see

Last update: Nov 22 2019 at 00:20UTC