@@ -2920,15 +2920,18 @@ $(H3 $(LNAME2 new_expressions, New Expressions))
2920
2920
2921
2921
$(GRAMMAR
2922
2922
$(GNAME NewExpression):
2923
- $(D new) $(GLINK2 type, Type)
2924
- $(D new) $(GLINK2 type, Type) $(D [) $(GLINK AssignExpression) $(D ])
2925
- $(D new) $(GLINK2 type, Type) $(D $(LPAREN)) $(GLINK NamedArgumentList)$(OPT) $(D $(RPAREN))
2923
+ $(D new) $(GLINK PlacementExpression)$(OPT) $( GLINK2 type, Type)
2924
+ $(D new) $(GLINK PlacementExpression)$(OPT) $( GLINK2 type, Type) $(D [) $(GLINK AssignExpression) $(D ])
2925
+ $(D new) $(GLINK PlacementExpression)$(OPT) $( GLINK2 type, Type) $(D $(LPAREN)) $(GLINK NamedArgumentList)$(OPT) $(D $(RPAREN))
2926
2926
$(GLINK2 class, NewAnonClassExpression)
2927
+
2928
+ $(GNAME PlacementExpression):
2929
+ $(LPAREN) $(GLINK AssignExpression) $(RPAREN)
2927
2930
)
2928
2931
2929
2932
$(P $(I NewExpression)s allocate memory on the
2930
2933
$(DDLINK spec/garbage, Garbage Collection, garbage
2931
- collected) heap by default .
2934
+ collected) heap unless there is a $(RELATIVE_LINK2 PlacementExpression, PlacementExpression) .
2932
2935
)
2933
2936
2934
2937
$(P `new T` constructs an instance of type `T` and default-initializes it.
@@ -3037,6 +3040,96 @@ $(H4 $(LNAME2 new_multidimensional, Multidimensional Arrays))
3037
3040
}
3038
3041
-----------
3039
3042
3043
+ $(H4 $(LNAME2 PlacementExpression, Placement Expression))
3044
+
3045
+ $(P The $(I PlacementExpression) explicitly provides the storage for $(I NewExpression) to initialize with
3046
+ the newly created value, rather than using the $(DDLINK spec/garbage, Garbage Collection, garbage
3047
+ collected) heap.)
3048
+
3049
+ $(P If $(I Type) is a basic type or a struct, the $(I PlacementExpression) must produce an lvalue that has a size
3050
+ larger or equal to $(D sizeof($(I Type))).)
3051
+
3052
+ $(P The $(I Type) of the $(I PlacementExpression) need not be the same as the $(I Type) of the object being created.)
3053
+
3054
+ $(P Alternatively, the $(I PlacementExpression) can be a dynamic array, which must represent sufficient memory
3055
+ for the object being created.)
3056
+
3057
+ $(BEST_PRACTICE Using a static array of `void` is preferred for the $(I PlacementExpression).)
3058
+
3059
+ $(P The lifetime of the object presented as an lvalue ends with the execution of the $(I NewExpression),
3060
+ and a new lifetime of the placed object starts after the execution.)
3061
+
3062
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
3063
+ ---
3064
+ struct S
3065
+ {
3066
+ float d;
3067
+ int i;
3068
+ char c;
3069
+ }
3070
+
3071
+ void main()
3072
+ {
3073
+ S s;
3074
+ S* p = new (s) S(); // lifetime of s ends, lifetime of *p begins
3075
+ assert(p.i == 0 && p.c == 0xFF);
3076
+ }
3077
+ ---
3078
+ )
3079
+
3080
+ (If Type is a class, the $(I PlacementExpression) must produce an lvalue of type that is of a
3081
+ sufficient size to hold the class object such as `void[__traits(classInstanceSize, Type)]`
3082
+ or a dynamic array representing sufficient memory for the class object.)
3083
+
3084
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
3085
+ ---
3086
+ class C
3087
+ {
3088
+ int i, j = 4;
3089
+ }
3090
+
3091
+ void main()
3092
+ {
3093
+ void[__traits(classInstanceSize, C)] k;
3094
+ C c = new(k) C;
3095
+ assert(c.j == 4);
3096
+ assert(cast(void*)c == cast(void*)k.ptr);
3097
+ }
3098
+ ---
3099
+ )
3100
+
3101
+ $(P $(I PlacementExpression) cannot be used for associative arrays, as associative arrays
3102
+ are designed to be on the GC heap. The size of the associative array allocated is determined
3103
+ by the runtime library, and cannot be set by the user.)
3104
+
3105
+ $(P The use of $(PlacementExpression) is not allowed in `@safe` code.)
3106
+
3107
+ $(P To allocate storage with an allocator function such as `malloc()`, a simple template can be used:)
3108
+
3109
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
3110
+ ---
3111
+ import core.stdc.stdlib;
3112
+
3113
+ struct S { int i = 1, j = 4, k = 9; }
3114
+
3115
+ ref void[T.sizeof] mallocate(T)()
3116
+ {
3117
+ return malloc(T.sizeof)[0 .. T.sizeof];
3118
+ }
3119
+
3120
+ void main()
3121
+ {
3122
+ S* ps = new(mallocate!S()) S;
3123
+ assert(ps.i == 1);
3124
+ assert(ps.j == 4);
3125
+ assert(ps.k == 9);
3126
+ }
3127
+ ---
3128
+ )
3129
+
3130
+
3131
+
3132
+
3040
3133
$(H3 $(LNAME2 typeid_expressions, Typeid Expressions))
3041
3134
3042
3135
$(GRAMMAR
0 commit comments