@@ -2974,15 +2974,18 @@ $(H3 $(LNAME2 new_expressions, New Expressions))
29742974
29752975$(GRAMMAR
29762976$(GNAME NewExpression):
2977- $(D new) $(GLINK2 type, Type)
2978- $(D new) $(GLINK2 type, Type) $(D [) $(GLINK AssignExpression) $(D ])
2979- $(D new) $(GLINK2 type, Type) $(D $(LPAREN)) $(GLINK NamedArgumentList)$(OPT) $(D $(RPAREN))
2977+ $(D new) $(GLINK PlacementExpression)$(OPT) $( GLINK2 type, Type)
2978+ $(D new) $(GLINK PlacementExpression)$(OPT) $( GLINK2 type, Type) $(D [) $(GLINK AssignExpression) $(D ])
2979+ $(D new) $(GLINK PlacementExpression)$(OPT) $( GLINK2 type, Type) $(D $(LPAREN)) $(GLINK NamedArgumentList)$(OPT) $(D $(RPAREN))
29802980 $(GLINK2 class, NewAnonClassExpression)
2981+
2982+ $(GNAME PlacementExpression):
2983+ $(LPAREN) $(GLINK AssignExpression) $(RPAREN)
29812984)
29822985
29832986 $(P $(I NewExpression)s allocate memory on the
29842987 $(DDLINK spec/garbage, Garbage Collection, garbage
2985- collected) heap by default .
2988+ collected) heap unless there is a $(RELATIVE_LINK2 placement-expression, *PlacementExpression*) .
29862989 )
29872990
29882991 $(P `new T` constructs an instance of type `T` and default-initializes it.
@@ -3091,6 +3094,96 @@ $(H4 $(LNAME2 new_multidimensional, Multidimensional Arrays))
30913094 }
30923095 -----------
30933096
3097+ $(H4 $(LNAME2 placement-expression, Placement Expression))
3098+
3099+ $(P The $(I PlacementExpression) explicitly provides the storage for $(I NewExpression) to initialize with
3100+ the newly created value, rather than using the $(DDLINK spec/garbage, Garbage Collection, garbage
3101+ collected) heap.)
3102+
3103+ $(P If $(I Type) is a basic type or a struct, the $(I PlacementExpression) must produce an lvalue that has a size
3104+ larger or equal to $(D sizeof($(I Type))).)
3105+
3106+ $(P The $(I Type) of the $(I PlacementExpression) need not be the same as the $(I Type) of the object being created.)
3107+
3108+ $(P Alternatively, the $(I PlacementExpression) can be a dynamic array, which must represent sufficient memory
3109+ for the object being created.)
3110+
3111+ $(BEST_PRACTICE Using a static array of `void` is preferred for the $(I PlacementExpression).)
3112+
3113+ $(P The lifetime of the object presented as an lvalue ends with the execution of the $(I NewExpression),
3114+ and a new lifetime of the placed object starts after the execution.)
3115+
3116+ $(SPEC_RUNNABLE_EXAMPLE_RUN
3117+ ---
3118+ struct S
3119+ {
3120+ float d;
3121+ int i;
3122+ char c;
3123+ }
3124+
3125+ void main()
3126+ {
3127+ S s;
3128+ S* p = new (s) S(); // lifetime of s ends, lifetime of *p begins
3129+ assert(p.i == 0 && p.c == 0xFF);
3130+ }
3131+ ---
3132+ )
3133+
3134+ (If Type is a class, the $(I PlacementExpression) must produce an lvalue of a type that is of a
3135+ sufficient size to hold the class object such as `void[__traits(classInstanceSize, Type)]`
3136+ or a dynamic array representing sufficient memory for the class object.)
3137+
3138+ $(SPEC_RUNNABLE_EXAMPLE_RUN
3139+ ---
3140+ class C
3141+ {
3142+ int i, j = 4;
3143+ }
3144+
3145+ void main()
3146+ {
3147+ void[__traits(classInstanceSize, C)] k = void;
3148+ C c = new(k) C;
3149+ assert(c.j == 4);
3150+ assert(cast(void*) c == k.ptr);
3151+ }
3152+ ---
3153+ )
3154+
3155+ $(P $(I PlacementExpression) cannot be used for associative arrays, as associative arrays
3156+ are designed to be on the GC heap. The size of the associative array allocated is determined
3157+ by the runtime library, and cannot be set by the user.)
3158+
3159+ $(P The use of $(I PlacementExpression) is not allowed in `@safe` code.)
3160+
3161+ $(P To allocate storage with an allocator function such as `malloc()`, a simple template can be used:)
3162+
3163+ $(SPEC_RUNNABLE_EXAMPLE_RUN
3164+ ---
3165+ import core.stdc.stdlib;
3166+
3167+ struct S { int i = 1, j = 4, k = 9; }
3168+
3169+ ref void[T.sizeof] mallocate(T)()
3170+ {
3171+ return malloc(T.sizeof)[0 .. T.sizeof];
3172+ }
3173+
3174+ void main()
3175+ {
3176+ S* ps = new(mallocate!S()) S;
3177+ assert(ps.i == 1);
3178+ assert(ps.j == 4);
3179+ assert(ps.k == 9);
3180+ }
3181+ ---
3182+ )
3183+
3184+
3185+
3186+
30943187$(H3 $(LNAME2 typeid_expressions, Typeid Expressions))
30953188
30963189$(GRAMMAR
0 commit comments