forked from cplusplus/draft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompatibility.tex
3681 lines (3304 loc) · 112 KB
/
compatibility.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%!TEX root = std.tex
\infannex{diff}{Compatibility}
\rSec1[diff.cpp23]{\Cpp{} and ISO \CppXXIII{}}
\rSec2[diff.cpp23.general]{General}
\pnum
\indextext{summary!compatibility with ISO \CppXXIII{}}%
Subclause \ref{diff.cpp23} lists the differences between \Cpp{} and
ISO \CppXXIII{},
by the chapters of this document.
\rSec2[diff.cpp23.expr]{\ref{expr}: expressions}
\diffref{expr.arith.conv}
\change
Operations mixing a value of an enumeration type and a value of a different
enumeration type or of a floating-point type are no longer valid.
\rationale
Reinforcing type safety.
\effect
A valid \CppXXIII{} program that performs operations mixing a value of an
enumeration type and a value of a different enumeration type or of a
floating-point type is ill-formed.
\begin{example}
\begin{codeblock}
enum E1 { e };
enum E2 { f };
bool b = e <= 3.7; // ill-formed; previously well-formed
int k = f - e; // ill-formed; previously well-formed
auto x = true ? e : f; // ill-formed; previously well-formed
\end{codeblock}
\end{example}
\diffref{expr.delete}
\change
Calling \tcode{delete} on a pointer to an incomplete class is ill-formed.
\rationale
Reduce undefined behavior.
\effect
A valid \CppXXIII{} program that calls \tcode{delete} on an incomplete
class type is ill-formed.
\begin{example}
\begin{codeblock}
struct S;
void f(S *p) {
delete p; // ill-formed; previously well-formed
}
struct S {};
\end{codeblock}
\end{example}
\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: declarations}
\diffref{dcl.init.list}
\change
Pointer comparisons between \tcode{initializer_list} objects' backing arrays
are unspecified.
\rationale
Permit the implementation to store backing arrays in static read-only memory.
\effect
Valid \CppXXIII{} code
that relies on the result of pointer comparison between backing arrays
may change behavior.
\begin{example}
\begin{codeblock}
bool ne(std::initializer_list<int> a, std::initializer_list<int> b) {
return a.begin() != b.begin() + 1;
}
bool b = ne({2,3}, {1,2,3}); // unspecified result; previously \tcode{false}
\end{codeblock}
\end{example}
\diffref{dcl.array}
\change
Previously, \tcode{T...[n]} would declare a pack of function parameters.
\tcode{T...[n]} is now a \grammarterm{pack-index-specifier}.
\rationale
Improve the handling of packs.
\effect
Valid \CppXXIII{} code that declares a pack of parameters
without specifying a \grammarterm{declarator-id} becomes ill-formed.
\begin{example}
\begin{codeblock}
template <typename... T>
void f(T... [1]);
template <typename... T>
void g(T... ptr[1]);
int main() {
f<int, double>(nullptr, nullptr); // ill-formed, previously \tcode{void f<int, double>(int [1], double [1])}
g<int, double>(nullptr, nullptr); // ok
}
\end{codeblock}
\end{example}
\rSec2[diff.cpp23.temp]{\ref{temp}: templates}
\diffref{temp.constr}
\change
Some atomic constraints become fold expanded constraints.
\rationale
Permit the subsumption of fold expressions.
\effect
Valid \CppXXIII{} code may become ill-formed.
\begin{example}
\begin{codeblock}
template <typename ...V> struct A;
struct S {
static constexpr int compare(const S&) { return 1; }
};
template <typename ...T, typename ...U>
void f(A<T ...> *, A<U ...> *)
requires (T::compare(U{}) && ...); // was well-formed (atomic constraint of type \tcode{bool}),
// now ill-formed (results in an atomic constraint of type \tcode{int})
void g(A<S, S> *ap) {
f(ap, ap);
}
\end{codeblock}
\end{example}
\rSec2[diff.cpp23.library]{\ref{library}: library introduction}
\diffref{headers}
\change
New headers.
\rationale
New functionality.
\effect
The following \Cpp{} headers are new:
\libheaderref{debugging},
\libheaderrefx{hazard_pointer}{hazard.pointer.syn},
\libheaderrefx{inplace_vector}{inplace.vector.syn},
\libheaderref{linalg},
\libheaderref{rcu}, and
\libheaderrefx{text_encoding}{text.encoding.syn}.
Valid \CppXXIII{} code that \tcode{\#include}{s} headers with these names may be
invalid in this revision of \Cpp{}.
\rSec2[diff.cpp23.strings]{\ref{strings}: strings library}
\diffref{string.conversions}
\change
Output of floating-point overloads of \tcode{to_string} and \tcode{to_wstring}.
\rationale
Prevent loss of information and improve consistency with other formatting
facilities.
\effect
\tcode{to_string} and \tcode{to_wstring} function calls that take
floating-point arguments may produce a different output.
\begin{example}
\begin{codeblock}
auto s = std::to_string(1e-7); // \tcode{"1e-07"}
// previously \tcode{"0.000000"} with \tcode{'.'} possibly
// changed according to the global C locale
\end{codeblock}
\end{example}
\rSec2[diff.cpp23.containers]{\ref{containers}: containers library}
\diffref{span.overview}
\change
\tcode{span<const T>} is constructible from \tcode{initializer_list<T>}.
\rationale
Permit passing a braced initializer list to a function taking \tcode{span}.
\effect
Valid \CppXXIII{} code that relies on the lack of this constructor
may refuse to compile, or change behavior in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
void one(pair<int, int>); // \#1
void one(span<const int>); // \#2
void t1() { one({1, 2}); } // ambiguous between \#1 and \#2; previously called \#1
void two(span<const int, 2>);
void t2() { two({{1, 2}}); } // ill-formed; previously well-formed
void *a[10];
int x = span<void* const>{a, 0}.size(); // \tcode{x} is \tcode{2}; previously \tcode{0}
any b[10];
int y = span<const any>{b, b + 10}.size(); // \tcode{y} is \tcode{2}; previously \tcode{10}
\end{codeblock}
\end{example}
\rSec2[diff.cpp23.depr]{\ref{depr}: compatibility features}
\nodiffref
\change
Remove the type alias \tcode{allocator<T>::is_always_equal}.
\rationale
Non-empty allocator classes derived from \tcode{allocator} needed to explicitly
define an \tcode{is_always_equal} member type so that \tcode{allocator_traits}
would not use the one from the allocator base class.
\effect
It is simpler to correctly define an allocator class with an allocator base
class.
\begin{example}
\begin{codeblock}
template <class T>
struct MyAlloc : allocator<T> {
int tag;
};
static_assert(!allocator_traits<MyAlloc<int>>::is_always_equal); // Error in \CppXXIII{},
// OK in \CppXXVI{}
\end{codeblock}
\end{example}
\nodiffref
\change
Removal of atomic access API for \tcode{shared_ptr} objects.
\rationale
The old behavior was brittle. \tcode{shared_ptr} objects using the old API were
not protected by the type system, and certain interactions with code not using
this API would, in some cases, silently produce undefined behavior. A complete
type-safe replacement is provided in the form of \tcode{atomic<shared_ptr<T>>}.
\effect
A valid \CppXXIII{} program that relies on the presence of the removed functions
may fail to compile.
\nodiffref
\change
Remove the \tcode{basic_string::reserve()} overload with no parameters.
\rationale
The overload of \tcode{reserve} with no parameters is redundant.
The \tcode{shrink_to_fit} member function can be used instead.
\effect
A valid \CppXXIII{} program that calls \tcode{reserve()}
on a \tcode{basic_string} object may fail to compile.
The old functionality can be achieved by calling \tcode{shrink_to_fit()} instead,
or the function call can be safely eliminated with no side effects.
\nodiffref
\change
Remove header \libnoheader{codecvt} and all its contents.
\rationale
The header has been deprecated for the previous three editions of this document
and no longer implements the current Unicode standard, supporting only the
obsolete UCS-2 encoding.
Ongoing support is at implementer's discretion,
exercising freedoms granted by \ref{zombie.names}.
\effect
A valid \CppXXIII{} program \tcode{\#include}-ing the header or importing the
header unit may fail to compile. Code that uses any of the following names by
importing the standard library modules may fail to compile:
\begin{itemize}
\item \tcode{codecvt_mode},
\item \tcode{codecvt_utf16},
\item \tcode{codecvt_utf8},
\item \tcode{codecvt_utf8_utf16},
\item \tcode{consume_header},
\item \tcode{generate_header}, and
\item \tcode{little_endian}.
\end{itemize}
\nodiffref
\change
Remove header \libnoheader{strstream} and all its contents.
\rationale
The header has been deprecated since the original \Cpp{} standard; the
\libheader{spanstream} header provides an updated, safer facility.
Ongoing support is at implementer's discretion,
exercising freedoms granted by \ref{zombie.names}.
\effect
A valid \CppXXIII{} program \tcode{\#include}-ing the header or importing the
header unit may become ill-formed. Code that uses any of the following classes
by importing one of the standard library modules may become ill-formed:
\begin{itemize}
\item \tcode{istrstream}
\item \tcode{ostrstream}
\item \tcode{strstream}
\item \tcode{strstreambuf}
\end{itemize}
\nodiffref
\change
Remove convenience interfaces \tcode{wstring_convert} and
\tcode{wbuffer_convert}.
\rationale
These features were underspecified with no clear error reporting mechanism and
were deprecated for the last three editions of this document.
Ongoing support is at implementer's discretion,
exercising freedoms granted by \ref{zombie.names}.
\effect
A valid \CppXXIII{} program using these interfaces may become ill-formed.
\rSec1[diff.cpp20]{\Cpp{} and ISO \CppXX{}}
\rSec2[diff.cpp20.general]{General}
\pnum
\indextext{summary!compatibility with ISO \CppXX{}}%
Subclause \ref{diff.cpp20} lists the differences between \Cpp{} and
ISO \CppXX{},
in addition to those listed above,
by the chapters of this document.
\rSec2[diff.cpp20.lex]{\ref{lex}: lexical conventions}
\diffref{lex.name}
\change
Previously valid identifiers containing characters
not present in \UAX{44} properties XID_Start or XID_Continue, or
not in Normalization Form C, are now rejected.
\rationale
Prevent confusing characters in identifiers.
Requiring normalization of names ensures consistent linker behavior.
\effect
Some identifiers are no longer well-formed.
\diffref{lex.string}
\change
Concatenated \grammarterm{string-literal}s can no longer have
conflicting \grammarterm{encoding-prefix}es.
\rationale
Removal of unimplemented conditionally-supported feature.
\effect
Concatenation of \grammarterm{string-literal}s
with different \grammarterm{encoding-prefix}es
is now ill-formed.
\begin{example}
\begin{codeblock}
auto c = L"a" U"b"; // was conditionally-supported; now ill-formed
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.expr]{\ref{expr}: expressions}
\diffref{expr.prim.id.unqual}
\change
Change move-eligible \grammarterm{id-expression}s from lvalues to xvalues.
\rationale
Simplify the rules for implicit move.
\effect
Valid \CppXX{} code that relies on a returned \grammarterm{id-expression}'s
being an lvalue may change behavior or fail to compile.
\begin{example}
\begin{codeblock}
decltype(auto) f(int&& x) { return (x); } // returns \tcode{int\&\&}; previously returned \tcode{int\&}
int& g(int&& x) { return x; } // ill-formed; previously well-formed
\end{codeblock}
\end{example}
\diffref{expr.sub}
\change
Change the meaning of comma in subscript expressions.
\rationale
Enable repurposing a deprecated syntax to support multidimensional indexing.
\effect
Valid \CppXX{} code that uses a comma expression within a
subscript expression may fail to compile.
\begin{example}
\begin{codeblock}
arr[1, 2] // was equivalent to \tcode{arr[(1, 2)]},
// now equivalent to \tcode{arr.operator[](1, 2)} or ill-formed
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.stmt]{\ref{stmt.stmt}: statements}
\diffref{stmt.ranged}
\change
The lifetime of temporary objects in the \grammarterm{for-range-initializer}
is extended until the end of the loop\iref{class.temporary}.
\rationale
Improve usability of the range-based \keyword{for} statement.
\effect
Destructors of some temporary objects are invoked later.
\begin{example}
\begin{codeblock}
void f() {
std::vector<int> v = { 42, 17, 13 };
std::mutex m;
for (int x :
static_cast<void>(std::lock_guard<std::mutex>(m)), v) { // lock released in \CppXX
std::lock_guard<std::mutex> guard(m); // OK in \CppXX, now deadlocks
}
}
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations}
\diffref{dcl.init.string}
\change
UTF-8 string literals may initialize arrays of \keyword{char} or
\tcode{\keyword{unsigned} \keyword{char}}.
\rationale
Compatibility with previously written code that conformed to previous versions of this document.
\effect
Arrays of \keyword{char} or \tcode{\keyword{unsigned} \keyword{char}}
may now be initialized with a UTF-8 string literal.
This can affect initialization that includes arrays
that are directly initialized within class types, typically aggregates.
\begin{example}
\begin{codeblock}
struct A {
char8_t s[10];
};
struct B {
char s[10];
};
void f(A);
void f(B);
int main() {
f({u8""}); // ambiguous
}
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.temp]{\ref{temp}: templates}
\diffref{temp.deduct.type}
\change
Deducing template arguments from exception specifications.
\rationale
Facilitate generic handling of throwing and non-throwing functions.
\effect
Valid ISO \CppXX{} code may be ill-formed in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
template<bool> struct A { };
template<bool B> void f(void (*)(A<B>) noexcept(B));
void g(A<false>) noexcept;
void h() {
f(g); // ill-formed; previously well-formed
}
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.library]{\ref{library}: library introduction}
\diffref{headers}
\change
New headers.
\rationale
New functionality.
\effect
The following \Cpp{} headers are new:
\libheaderref{expected},
\libheaderrefx{flat_map}{flat.map.syn},
\libheaderrefx{flat_set}{flat.set.syn},
\libheaderref{generator},
\libheaderref{mdspan},
\libheaderref{print},
\libheaderref{spanstream},
\libheaderref{stacktrace},
\libheaderref{stdatomic.h}, and
\libheaderref{stdfloat}.
Valid \CppXX{} code that \tcode{\#include}{s} headers with these names may be
invalid in this revision of \Cpp{}.
\rSec2[diff.cpp20.concepts]{\ref{concepts}: concepts library}
\diffref{cmp.concept,concept.equalitycomparable,concept.totallyordered}
\change
Replace \tcode{common_reference_with} in \tcode{three_way_comparable_with},
\tcode{equality_comparable_with}, and \tcode{totally_ordered_with}
with an exposition-only concept.
\rationale
Allow uncopyable, but movable, types to model these concepts.
\effect
Valid \CppXX{} code relying on subsumption
with \tcode{common_reference_with}
may fail to compile in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
template<class T, class U>
requires @\libconcept{equality_comparable_with}@<T, U>
bool attempted_equals(const T&, const U& u); // previously selected overload
template<class T, class U>
requires @\libconcept{common_reference_with}@<const remove_reference_t<T>&, const remove_reference_t<U>&>
bool attempted_equals(const T& t, const U& u); // ambiguous overload; previously
// rejected by partial ordering
bool test(shared_ptr<int> p) {
return attempted_equals(p, nullptr); // ill-formed; previously well-formed
}
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.memory]{\ref{mem}: memory management library}
\diffref{allocator.traits.general}
\change
Forbid partial and explicit program-defined specializations
of \tcode{allocator_traits}.
\rationale
Allow addition of \tcode{allocate_at_least} to \tcode{allocator_traits},
and potentially other members in the future.
\effect
Valid \CppXX{} code
that partially or explicitly specializes \tcode{allocator_traits}
is ill-formed with no diagnostic required in this revision of \Cpp{}.
\rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library}
\diffref{format}
\change
Signature changes: \tcode{format}, \tcode{format_to}, \tcode{vformat_to},
\tcode{format_to_n}, \tcode{formatted_size}.
Removal of \tcode{format_args_t}.
\rationale
Improve safety via compile-time format string checks,
avoid unnecessary template instantiations.
\effect
Valid \CppXX{} code that
contained errors in format strings or
relied on previous format string signatures or
\tcode{format_args_t} may become ill-formed.
\begin{example}
\begin{codeblock}
auto s = std::format("{:d}", "I am not a number"); // ill-formed,
// previously threw \tcode{format_error}
\end{codeblock}
\end{example}
\diffref{format}
\change
Signature changes: \tcode{format}, \tcode{format_to}, \tcode{format_to_n},
\tcode{formatted_size}.
\rationale
Enable formatting of views
that do not support iteration when const-qualified and
that are not copyable.
\effect
Valid \CppXX{} code that passes bit-fields to formatting functions
may become ill-formed.
\begin{example}
\begin{codeblock}
struct tiny {
int bit: 1;
};
auto t = tiny();
std::format("{}", t.bit); // ill-formed, previously returned \tcode{"0"}
\end{codeblock}
\end{example}
\diffref{format.string.std}
\change
Restrict types of formatting arguments
used as \fmtgrammarterm{width} or \fmtgrammarterm{precision} in
a \fmtgrammarterm{std-format-spec}.
\rationale
Disallow types that do not have useful or portable semantics as
a formatting width or precision.
\effect
Valid \CppXX{} code that passes a boolean or character type as
\fmtgrammarterm{arg-id} becomes invalid.
\begin{example}
\begin{codeblock}
std::format("{:*^{}}", "", true); // ill-formed, previously returned \tcode{"*"}
std::format("{:*^{}}", "", '1'); // ill-formed, previously returned an
// implementation-defined number of \tcode{'*'} characters
\end{codeblock}
\end{example}
\diffref{format.formatter.spec}
\change
Removed the \tcode{formatter} specialization:
\begin{codeblock}
template<size_t N> struct formatter<const charT[N], charT>;
\end{codeblock}
\rationale
The specialization is inconsistent with the design of \tcode{formatter},
which is intended to be instantiated only with cv-unqualified object types.
\effect
Valid \CppXX{} code that instantiated the removed specialization
can become ill-formed.
\rSec2[diff.cpp20.strings]{\ref{strings}: strings library}
\diffref{string.classes}
\change
Additional rvalue overload for the \tcode{substr} member function and
the corresponding constructor.
\rationale
Improve efficiency of operations on rvalues.
\effect
Valid \CppXX{} code that created a substring
by calling \tcode{substr} (or the corresponding constructor)
on an xvalue expression with type \tcode{S}
that is a specialization of \tcode{basic_string}
may change meaning in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
std::string s1 = "some long string that forces allocation", s2 = s1;
std::move(s1).substr(10, 5);
assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true}
std::string s3(std::move(s2), 10, 5);
assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true}
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.containers]{\ref{containers}: containers library}
\diffref{associative.reqmts,unord.req}
\change
Heterogeneous \tcode{extract} and \tcode{erase} overloads
for associative containers.
\rationale
Improve efficiency of erasing elements from associative containers.
\effect
Valid \CppXX{} code may fail to compile in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
struct B {
auto operator<=>(const B&) const = default;
};
struct D : private B {
void f(std::set<B, std::less<>>& s) {
s.erase(*this); // ill-formed; previously well-formed
}
};
\end{codeblock}
\end{example}
\rSec2[diff.cpp20.thread]{\ref{thread}: concurrency support library}
\diffref{thread.barrier}
\change
In this revision of \Cpp{},
it is implementation-defined whether a barrier's phase completion step runs
if no thread calls \tcode{wait}.
Previously the phase completion step was guaranteed to run on the last thread that calls \tcode{arrive} or \tcode{arrive_and_drop} during the phase.
In this revision of \Cpp{},
it can run on any of the threads that arrived or waited at the barrier
during the phase.
\rationale
Correct contradictory wording and
improve implementation flexibility for performance.
\effect
Valid \CppXX{} code using a barrier might have
different semantics in this revision of \Cpp{}
if it depends on a completion function's side effects occurring exactly once,
on a specific thread running the phase completion step, or
on a completion function's side effects occurring
without \tcode{wait} having been called.
\begin{example}
\begin{codeblock}
auto b0 = std::barrier(1);
b0.arrive();
b0.arrive(); // implementation-defined; previously well-defined
int data = 0;
auto b1 = std::barrier(1, [&] { data++; });
b1.arrive();
assert(data == 1); // implementation-defined; previously well-defined
b1.arrive(); // implementation-defined; previously well-defined
\end{codeblock}
\end{example}
\rSec1[diff.cpp17]{\Cpp{} and ISO \CppXVII{}}
\rSec2[diff.cpp17.general]{General}
\pnum
\indextext{summary!compatibility with ISO \CppXVII{}}%
Subclause \ref{diff.cpp17} lists the differences between \Cpp{} and
ISO \CppXVII{},
in addition to those listed above,
by the chapters of this document.
\rSec2[diff.cpp17.lex]{\ref{lex}: lexical conventions}
\diffref{lex.pptoken,module.unit,module.import,cpp.pre,cpp.module,cpp.import}
\change
New identifiers with special meaning.
\rationale
Required for new features.
\effect
Logical lines beginning with
\tcode{module} or \tcode{import} may
be interpreted differently
in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
class module {};
module m1; // was variable declaration; now \grammarterm{module-declaration}
module *m2; // variable declaration
class import {};
import j1; // was variable declaration; now \grammarterm{module-import-declaration}
::import j2; // variable declaration
\end{codeblock}
\end{example}
\diffref{lex.header}
\change
\grammarterm{header-name} tokens are formed in more contexts.
\rationale
Required for new features.
\effect
When the identifier \tcode{import}
is followed by a \tcode{<} character,
a \grammarterm{header-name} token may be formed.
\begin{example}
\begin{codeblock}
template<typename> class import {};
import<int> f(); // ill-formed; previously well-formed
::import<int> g(); // OK
\end{codeblock}
\end{example}
\diffref{lex.key}
\change
New keywords.
\rationale
Required for new features.
\begin{itemize}
\item
\indextext{UTF-8}%
The \keyword{char8_t} keyword is added to differentiate
the types of ordinary and UTF-8 literals\iref{lex.string}.
\item
The \tcode{concept} keyword is
added to enable the definition of concepts\iref{temp.concept}.
\item
The \keyword{consteval} keyword is added to
declare immediate functions\iref{dcl.constexpr}.
\item
The \keyword{constinit} keyword is added to
prevent unintended dynamic initialization\iref{dcl.constinit}.
\item
The \keyword{co_await}, \keyword{co_yield}, and \keyword{co_return} keywords are added
to enable the definition of coroutines \iref{dcl.fct.def.coroutine}.
\item
The \tcode{requires} keyword is added
to introduce constraints through a \grammarterm{requires-clause}\iref{temp.pre}
or a \grammarterm{requires-expression}\iref{expr.prim.req}.
\end{itemize}
\effectafteritemize
Valid \CppXVII{} code using
\keyword{char8_t},
\tcode{concept},
\keyword{consteval},
\keyword{constinit},
\keyword{co_await}, \keyword{co_yield}, \keyword{co_return},
or \tcode{requires}
as an identifier is not valid in this revision of \Cpp{}.
\diffref{lex.operators}
\change
New operator \tcode{<=>}.
\rationale
Necessary for new functionality.
\effect
Valid \CppXVII{} code that contains a \tcode{<=} token
immediately followed by a \tcode{>} token
may be ill-formed or have different semantics in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
namespace N {
struct X {};
bool operator<=(X, X);
template<bool(X, X)> struct Y {};
Y<operator<=> y; // ill-formed; previously well-formed
}
\end{codeblock}
\end{example}
\diffref{lex.literal}
\indextext{UTF-8}%
\change
Type of UTF-8 string and character literals.
\rationale
Required for new features.
The changed types enable function overloading, template specialization, and
type deduction to distinguish ordinary and UTF-8 string and character literals.
\effect
Valid \CppXVII{} code that depends on
UTF-8 string literals having type ``array of \tcode{const char}'' and
UTF-8 character literals having type ``\tcode{char}''
is not valid in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
const auto *u8s = u8"text"; // \tcode{u8s} previously deduced as \tcode{const char*}; now deduced as \tcode{const char8_t*}
const char *ps = u8s; // ill-formed; previously well-formed
auto u8c = u8'c'; // \tcode{u8c} previously deduced as \tcode{char}; now deduced as \keyword{char8_t}
char *pc = &u8c; // ill-formed; previously well-formed
std::string s = u8"text"; // ill-formed; previously well-formed
void f(const char *s);
f(u8"text"); // ill-formed; previously well-formed
template<typename> struct ct;
template<> struct ct<char> {
using type = char;
};
ct<decltype(u8'c')>::type x; // ill-formed; previously well-formed.
\end{codeblock}
\end{example}
\rSec2[diff.cpp17.basic]{\ref{basic}: basics}
\diffref{basic.life}
\change
A pseudo-destructor call ends the lifetime of
the object to which it is applied.
\rationale
Increase consistency of the language model.
\effect
Valid ISO \CppXVII{} code may be ill-formed or
have undefined behavior in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
int f() {
int a = 123;
using T = int;
a.~T();
return a; // undefined behavior; previously returned 123
}
\end{codeblock}
\end{example}
\diffref{intro.races}
\change
Except for the initial release operation,
a release sequence consists solely of atomic read-modify-write operations.
\rationale
Removal of rarely used and confusing feature.
\effect
If a \tcode{memory_order_release} atomic store is followed
by a \tcode{memory_order_relaxed} store to the same variable by the same thread,
then reading the latter value with a \tcode{memory_order_acquire} load
no longer provides any ``happens before'' guarantees,
even in the absence of intervening stores by another thread.
\rSec2[diff.cpp17.expr]{\ref{expr}: expressions}
\diffref{expr.prim.lambda.capture}
\change
Implicit lambda capture may capture additional entities.
\rationale
Rule simplification, necessary to resolve interactions with constexpr if.
\effect
Lambdas with a \grammarterm{capture-default}
may capture local entities
that were not captured in \CppXVII{}
if those entities are only referenced in contexts
that do not result in an odr-use.
\rSec2[diff.cpp17.dcl.dcl]{\ref{dcl.dcl}: declarations}
\diffref{dcl.typedef}
\change
Unnamed classes with a typedef name for linkage purposes
can contain only C-compatible constructs.
\rationale
Necessary for implementability.
\effect
Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
typedef struct {
void f() {} // ill-formed; previously well-formed
} S;
\end{codeblock}
\end{example}
\diffref{dcl.fct.default}
\change
A function cannot have different default arguments
in different translation units.
\rationale
Required for modules support.
\effect
Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{},
with no diagnostic required.
\begin{example}
\begin{codeblock}
// Translation unit 1
int f(int a = 42);
int g() { return f(); }
// Translation unit 2
int f(int a = 76) { return a; } // ill-formed, no diagnostic required; previously well-formed
int g();
int main() { return g(); } // used to return 42
\end{codeblock}
\end{example}
\diffref{dcl.init.aggr}
\change
A class that has user-declared constructors is never an aggregate.
\rationale
Remove potentially error-prone aggregate initialization
which may apply notwithstanding the declared constructors of a class.
\effect
Valid \CppXVII{} code that aggregate-initializes
a type with a user-declared constructor
may be ill-formed or have different semantics
in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
struct A { // not an aggregate; previously an aggregate
A() = delete;
};
struct B { // not an aggregate; previously an aggregate
B() = default;
int i = 0;
};
struct C { // not an aggregate; previously an aggregate
C(C&&) = default;
int a, b;
};
A a{}; // ill-formed; previously well-formed
B b = {1}; // ill-formed; previously well-formed
auto* c = new C{2, 3}; // ill-formed; previously well-formed
struct Y;
struct X {
operator Y();
};
struct Y { // not an aggregate; previously an aggregate
Y(const Y&) = default;
X x;
};
Y y{X{}}; // copy constructor call; previously aggregate-initialization
\end{codeblock}
\end{example}
\diffref{dcl.init.list}
\change
Boolean conversion from a pointer or pointer-to-member type
is now a narrowing conversion.
\rationale
Catches bugs.
\effect
Valid \CppXVII{} code may fail to compile
in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
bool y[] = { "bc" }; // ill-formed; previously well-formed
\end{codeblock}
\end{example}
\rSec2[diff.cpp17.class]{\ref{class}: classes}
\diffref{class.ctor,class.conv.fct}
\change
The class name can no longer be used parenthesized
immediately after an \keyword{explicit} \grammarterm{decl-specifier}
in a constructor declaration.
The \grammarterm{conversion-function-id} can no longer be used parenthesized
immediately after an \keyword{explicit} \grammarterm{decl-specifier}
in a conversion function declaration.
\rationale
Necessary for new functionality.
\effect
Valid \CppXVII{} code may fail to compile
in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
struct S {
explicit (S)(const S&); // ill-formed; previously well-formed
explicit (operator int)(); // ill-formed; previously well-formed
explicit(true) (S)(int); // OK
};
\end{codeblock}
\end{example}
\diffref{class.ctor,class.dtor}
\change
A \grammarterm{simple-template-id}
is no longer valid as the \grammarterm{declarator-id} of a constructor or destructor.
\rationale
Remove potentially error-prone option for redundancy.
\effect
Valid \CppXVII{} code may fail to compile
in this revision of \Cpp{}.
\begin{example}
\begin{codeblock}
template<class T>
struct A {
A<T>(); // error: \grammarterm{simple-template-id} not allowed for constructor
A(int); // OK, injected-class-name used
~A<T>(); // error: \grammarterm{simple-template-id} not allowed for destructor
};
\end{codeblock}
\end{example}
\diffref{class.copy.elision}
\change