Jump to page: 1 2
Thread overview
Placement new and @trusted
2 days ago
IchorDev
2 days ago
IchorDev
2 days ago
IchorDev
2 days ago
IchorDev
1 day ago
IchorDev
2 days ago
Paul Backus
1 day ago
IchorDev
21 hours ago
Nick Treleaven
1 day ago
Dennis
1 day ago
Paul Backus
21 hours ago
IchorDev
21 hours ago
IchorDev
2 days ago

I thought the 'placement new' feature might replace my need for emplace, but I don't see a way to mark a placement new as @trusted without marking the call to the object's constructor as @trusted also?

void main() @safe{
	X x;
	//placement new is @system, so we have to wrap it in @trusted:
	X* xPtr = (() @trusted => new (x) X(500))();
}

struct X{
	void* a;
	this(int a) @system{
		//but we don't want to mark THIS as @trusted!
		this.a = cast(void*)a;
	}
}

If anyone has any ideas, please let me know.

2 days ago
On 11/09/2025 12:29 AM, IchorDev wrote:
> I thought the 'placement new' feature might replace my need for `emplace`, but I don't see a way to mark a placement new as `@trusted` without marking the call to the object's constructor as `@trusted` also?
> 
> ```d
> void main() @safe{
>      X x;
>      //placement new is @system, so we have to wrap it in @trusted:
>      X* xPtr = (() @trusted => new (x) X(500))();
> }
> 
> struct X{
>      void* a;
>      this(int a) @system{
>          //but we don't want to mark THIS as @trusted!
>          this.a = cast(void*)a;
>      }
> }
> ```
> 
> If anyone has any ideas, please let me know.

Your calling a @system function (constructor) from a safe function (main).

Placement new doesn't change the rules around this.
2 days ago

On Wednesday, 10 September 2025 at 12:41:22 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

Your calling a @system function (constructor) from a safe function (main).

Placement new doesn't change the rules around this.

You don't understand: I WANT the code FAIL to compile because S's constructor is @system. But instead, the @system constructor gets through because I had to use @trusted to get placement new itself to be considered safe. If I have to manually check constructor safety to get around this then I might as well just use emplace, which would make this a completely worthless feature.

2 days ago
Ok, gotcha.

Placement new is @system, but you wanted to use it in an @safe function iff the constructor to be called is @safe as well.

The reason placement new is @system is because of double-init. It can't be a safe operation.
2 days ago

On Wednesday, 10 September 2025 at 13:13:34 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

Placement new is @system, but you wanted to use it in an @safe function iff the constructor to be called is @safe as well.

Pretty much.

>

The reason placement new is @system is because of double-init. It can't be a safe operation.

What?! Like, it assigns to the memory twice? What's the point of this feature, then? I thought this could essentially replace emplace for constructing types into uninitialised memory, but instead it's just a booby-trap that stops people from making their code @safe?

2 days ago
On 11/09/2025 2:31 AM, IchorDev wrote:
> On Wednesday, 10 September 2025 at 13:13:34 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> The reason placement new is @system is because of double-init. It can't be a safe operation.
> 
> What?! Like, it assigns to the memory twice? What's the point of this feature, then? I thought this could essentially replace `emplace` for constructing types into uninitialised memory, but instead it's just a booby-trap that stops people from making their code `@safe`?

It does replace emplace, and just like emplace you can double-init memory with it. There is no protection against it apart from it being @system (which emplace should also be).

The caller is responsible for guaranteeing that the memory passed in is uninitialized, and that behavior is @system.
2 days ago

On Wednesday, 10 September 2025 at 14:45:52 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

The caller is responsible for guaranteeing that the memory passed in is uninitialized, and that behavior is @system.

Yeah but I should be able to mark it as @trusted without trusting some random bloody constructor as well. Apparently nobody thought to use a syntax that allows marking one but not the other? This is why we need to use the DIP process to add new features like this.

2 days ago
On 11/09/2025 3:27 AM, IchorDev wrote:
> On Wednesday, 10 September 2025 at 14:45:52 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> The caller is responsible for guaranteeing that the memory passed in is uninitialized, and that behavior is @system.
> 
> Yeah but I should be able to mark it as `@trusted` without trusting some random bloody constructor as well. Apparently nobody thought to use a syntax that allows marking one but not the other? This is why we need to use the DIP process to add new features like this.

It did go through the DIP process.

What has not gone through the DIP process is attributes like @localtrusted which would be more akin to what you're asking about.
2 days ago

On Wednesday, 10 September 2025 at 14:31:27 UTC, IchorDev wrote:

>

On Wednesday, 10 September 2025 at 13:13:34 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

Placement new is @system, but you wanted to use it in an @safe function iff the constructor to be called is @safe as well.

Pretty much.

>

The reason placement new is @system is because of double-init. It can't be a safe operation.

What?! Like, it assigns to the memory twice? What's the point of this feature, then? I thought this could essentially replace emplace for constructing types into uninitialised memory, but instead it's just a booby-trap that stops people from making their code @safe?

The problem is not really with placement new, it's with constructors. Constructors are allowed to mutate immutable objects (under the assumption that they are initializing a newly-created object). If you call a constructor twice on the same immutable object, which is possible with placement new, it can result in undefined behavior.

In fact, it is also possible to trigger UB this way by simply calling the constructor manually: https://github.com/dlang/dmd/issues/20248

1 day ago

On Thursday, 11 September 2025 at 04:19:02 UTC, Paul Backus wrote:

>

The problem is not really with placement new, it's with constructors. Constructors are allowed to mutate immutable objects (under the assumption that they are initializing a newly-created object). If you call a constructor twice on the same immutable object, which is possible with placement new, it can result in undefined behavior.

But that's the thing: all I want is to construct objects into freshly-allocated, uninitialised memory; so my desired use-case has a safe interface and can therefore be marked @trusted. However the constructor is a wildcard, so I want to leave that part to attribute inference.
Do you think it'd be worth submitting an enhancement issue to add something simple like this?

new @trusted (buffer) S(500); //we trust that the buffer is safe to use, but not S's constructor.

The weird placement new syntax means that this looks a bit goofy, but it's better than the feature being essentially dead-on-arrival for the one thing I'd ever want it for.

« First   ‹ Prev
1 2