forked from cplusplus/draft
/
compatibility.tex
2981 lines (2660 loc) · 91.9 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.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{} (ISO/IEC 14882:2020, \doccite{Programming Languages --- \Cpp{}}),
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.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. For 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}
\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},
\libheaderref{stdatomic.h},
\libheaderref{spanstream}, and
\libheaderref{stacktrace}.
Valid \CppXX{} code that \tcode{\#include}{s} headers with these names may be
invalid 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.
For example:
\begin{codeblock}
auto s = std::format("{:d}", "I am not a number"); // ill-formed,
// previously threw \tcode{format_error}
\end{codeblock}
\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. For example:
\begin{codeblock}
struct tiny {
int bit: 1;
};
auto t = tiny();
std::format("{}", t.bit); // ill-formed, previously returned \tcode{"0"}
\end{codeblock}
\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{}.
For 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}
\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{} (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp{}}),
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{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}
\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{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}
\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{codeblock}
typedef struct {
void f() {} // ill-formed; previously well-formed
} S;
\end{codeblock}
\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{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}
\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{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}
\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{}. For example:
\begin{codeblock}
bool y[] = { "bc" }; // ill-formed; previously well-formed
\end{codeblock}
\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{}. For 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}
\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{}. For 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}
\diffref{class.copy.elision}
\change
A function returning an implicitly movable entity
may invoke a constructor taking an rvalue reference to a type
different from that of the returned expression.
Function and catch-clause parameters can be thrown using move constructors.
\rationale
Side effect of making it easier to write
more efficient code that takes advantage of moves.
\effect
Valid \CppXVII{} code may fail to compile or have different semantics
in this revision of \Cpp{}.
For example:
\begin{codeblock}
struct base {
base();
base(base const &);
private:
base(base &&);
};
struct derived : base {};
base f(base b) {
throw b; // error: \tcode{base(base \&\&)} is private
derived d;
return d; // error: \tcode{base(base \&\&)} is private
}
struct S {
S(const char *s) : m(s) { }
S(const S&) = default;
S(S&& other) : m(other.m) { other.m = nullptr; }
const char * m;
};
S consume(S&& s) { return s; }
void g() {
S s("text");
consume(static_cast<S&&>(s));
char c = *s.m; // undefined behavior; previously ok
}
\end{codeblock}
\rSec2[diff.cpp17.over]{\ref{over}: overloading}
\diffref{over.match.oper}
\change
Equality and inequality expressions can now find
reversed and rewritten candidates.
\rationale
Improve consistency of equality with three-way comparison
and make it easier to write the full complement of equality operations.
\effect
Equality and inequality expressions between two objects of different types,
where one is convertible to the other,
could invoke a different operator.
Equality and inequality expressions between two objects of the same type
could become ambiguous.
\begin{codeblock}
struct A {
operator int() const;
};
bool operator==(A, int); // \#1
// \#2 is built-in candidate: \tcode{bool operator==(int, int);}
// \#3 is built-in candidate: \tcode{bool operator!=(int, int);}
int check(A x, A y) {
return (x == y) + // ill-formed; previously well-formed
(10 == x) + // calls \#1, previously selected \#2
(10 != x); // calls \#1, previously selected \#3
}
\end{codeblock}
\rSec2[diff.cpp17.temp]{\ref{temp}: templates}
\diffref{temp.names}
\change
An \grammarterm{unqualified-id}
that is followed by a \tcode{<}
and for which name lookup
finds nothing or finds a function
will be treated as a \grammarterm{template-name}
in order to potentially cause argument dependent lookup to be performed.
\rationale
It was problematic to call a function template
with an explicit template argument list
via argument dependent lookup
because of the need to have a template with the same name
visible via normal lookup.
\effect
Previously valid code that uses a function name
as the left operand of a \tcode{<} operator
would become ill-formed.
\begin{codeblock}
struct A {};
bool operator<(void (*fp)(), A);
void f() {}
int main() {
A a;
f < a; // ill-formed; previously well-formed
(f) < a; // still well formed
}
\end{codeblock}
\rSec2[diff.cpp17.except]{\ref{except}: exception handling}
\diffref{except.spec}
\change
Remove \tcode{throw()} exception specification.
\rationale
Removal of obsolete feature that has been replaced by \keyword{noexcept}.
\effect
A valid \CppXVII{} function declaration, member function declaration, function
pointer declaration, or function reference declaration that uses \tcode{throw()}
for its exception specification will be rejected as ill-formed in this
revision of \Cpp{}. It should simply be replaced with \keyword{noexcept} for no
change of meaning since \CppXVII{}.
\begin{note}
There is no way to write a function declaration
that is non-throwing in this revision of \Cpp{}
and is also non-throwing in \CppIII{}
except by using the preprocessor to generate
a different token sequence in each case.
\end{note}
\rSec2[diff.cpp17.library]{\ref{library}: library introduction}
\diffref{headers}
\change
New headers.
\rationale
New functionality.
\effect
The following \Cpp{} headers are new:
\libheaderref{barrier},
\libheaderref{bit},
\libheaderref{charconv},
\libheaderref{compare},
\libheaderref{concepts},
\libheaderref{coroutine},
\libheaderref{format},
\libheaderref{latch},
\libheaderref{numbers},
\libheaderref{ranges},
\libheaderref{semaphore},
\libheaderrefx{source_location}{source.location.syn},
\libheaderref{span},
\libheaderrefx{stop_token}{thread.stoptoken.syn},
\libheaderref{syncstream}, and
\libheaderrefx{version}{support.limits.general}.
Valid \CppXVII{} code that \tcode{\#include}{s} headers with these names may be
invalid in this revision of \Cpp{}.
\diffref{headers}
\change
Remove vacuous \Cpp{} header files.
\rationale
The empty headers implied a false requirement to achieve C compatibility with the \Cpp{} headers.
\effect
A valid \CppXVII{} program that \tcode{\#include}{s} any of the following headers may fail to compile:
\libnoheader{ccomplex},
\libnoheader{ciso646},
\libnoheader{cstdalign},
\libnoheader{cstdbool}, and
\libnoheader{ctgmath}.
To retain the same behavior:
\begin{itemize}
\item
a \tcode{\#include} of \libnoheader{ccomplex} can be replaced by
a \tcode{\#include} of \libheaderref{complex},
\item
a \tcode{\#include} of \libnoheader{ctgmath} can be replaced by
a \tcode{\#include} of \libheaderref{cmath} and
a \tcode{\#include} of \libheader{complex},
and
\item
a \tcode{\#include} of
\libnoheader{ciso646},
\libnoheader{cstdalign}, or
\libnoheader{cstdbool}
can simply be removed.
\end{itemize}
\rSec2[diff.cpp17.containers]{\ref{containers}: containers library}
\diffref{forward.list,list}
\change
Return types of \tcode{remove}, \tcode{remove_if}, and \tcode{unique}
changed from \keyword{void} to \tcode{container::size_type}.
\rationale
Improve efficiency and convenience of finding number of removed elements.
\effect
Code that depends on the return types might have different semantics in this revision of \Cpp{}.
Translation units compiled against this version of \Cpp{} may be incompatible with
translation units compiled against \CppXVII{}, either failing to link or having undefined behavior.
\rSec2[diff.cpp17.iterators]{\ref{iterators}: iterators library}
\diffref{iterator.traits}
\change
The specialization of \tcode{iterator_traits} for \tcode{void*} and
for function pointer types no longer contains any nested typedefs.
\rationale
Corrects an issue misidentifying pointer types that are not incrementable
as iterator types.
\effect
A valid \CppXVII{} program that relies on the presence of the typedefs
may fail to compile, or have different behavior.
\rSec2[diff.cpp17.alg.reqs]{\ref{algorithms}: algorithms library}
\diffref{algorithms.requirements}
\change
The number and order of deducible template parameters for algorithm declarations
is now unspecified, instead of being as-declared.
\rationale
Increase implementor freedom and allow some function templates
to be implemented as function objects with templated call operators.
\effect
A valid \CppXVII{} program that passes explicit template arguments to
algorithms not explicitly specified to allow such in this version of \Cpp{}
may fail to compile or have undefined behavior.
\rSec2[diff.cpp17.input.output]{\ref{input.output}: input/output library}
\diffref{istream.extractors}
\change
Character array extraction only takes array types.
\rationale
Increase safety via preventing buffer overflow at compile time.
\effect
Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}:
\begin{codeblock}
auto p = new char[100];
char q[100];
std::cin >> std::setw(20) >> p; // ill-formed; previously well-formed
std::cin >> std::setw(20) >> q; // OK
\end{codeblock}
\diffref{ostream.inserters.character}
\indextext{UTF-8}%
\change
Overload resolution for ostream inserters used with UTF-8 literals.
\rationale
Required for new features.
\effect
Valid \CppXVII{} code that passes UTF-8 literals to
\tcode{basic_ostream<char, ...>::operator<<} or
\tcode{basic_ostream<wchar_t, ...>::operator<<} is now ill-formed.
\begin{codeblock}
std::cout << u8"text"; // previously called \tcode{operator<<(const char*)} and printed a string;
// now ill-formed
std::cout << u8'X'; // previously called \tcode{operator<<(char)} and printed a character;
// now ill-formed
\end{codeblock}
\diffref{ostream.inserters.character}
\change
Overload resolution for ostream inserters
used with \keyword{wchar_t}, \keyword{char16_t}, or \keyword{char32_t} types.
\rationale
Removal of surprising behavior.
\effect
Valid \CppXVII{} code that passes
\keyword{wchar_t}, \keyword{char16_t}, or \keyword{char32_t} characters or strings
to \tcode{basic_ostream<char, ...>::operator<<} or
that passes \keyword{char16_t} or \keyword{char32_t} characters or strings
to \tcode{basic_ostream<wchar_t, ...>::operator<<} is now ill-formed.
\begin{codeblock}
std::cout << u"text"; // previously formatted the string as a pointer value;
// now ill-formed
std::cout << u'X'; // previously formatted the character as an integer value;
// now ill-formed
\end{codeblock}
\diffref{fs.class.path}
\change
Return type of filesystem path format observer member functions.
\rationale
Required for new features.
\effect
Valid \CppXVII{} code that depends on the \tcode{u8string()} and
\tcode{generic_u8string()} member functions of \tcode{std::filesystem::path}
returning \tcode{std::string} is not valid in this revision of \Cpp{}.
\begin{codeblock}
std::filesystem::path p;
std::string s1 = p.u8string(); // ill-formed; previously well-formed
std::string s2 = p.generic_u8string(); // ill-formed; previously well-formed
\end{codeblock}
\rSec2[diff.cpp17.depr]{\ref{depr}: compatibility features}
\nodiffref
\change
Remove \tcode{uncaught_exception}.
\rationale
The function did not have a clear specification when multiple exceptions were
active, and has been superseded by \tcode{uncaught_exceptions}.
\effect
A valid \CppXVII{} program that calls \tcode{std::uncaught_exception} may fail
to compile. It can be revised to use \tcode{std::uncaught_exceptions} instead,
for clear and portable semantics.
\nodiffref
\change
Remove support for adaptable function API.
\rationale
The deprecated support relied on a limited convention that could not be
extended to support the general case or new language features. It has been
superseded by direct language support with \keyword{decltype}, and by the
\tcode{std::bind} and \tcode{std::not_fn} function templates.
\effect
A valid \CppXVII{} program that relies on the presence of \tcode{result_type},
\tcode{argument_type}, \tcode{first_argument_type}, or
\tcode{second_argument_type} in a standard library class may fail to compile. A
valid \CppXVII{} program that calls \tcode{not1} or \tcode{not2}, or uses the
class templates \tcode{unary_negate} or \tcode{binary_negate}, may fail to
compile.
\nodiffref
\change
Remove redundant members from \tcode{std::allocator}.
\rationale
\tcode{std::allocator} was overspecified, encouraging direct usage in user containers
rather than relying on \tcode{std::allocator_traits}, leading to poor containers.
\effect
A valid \CppXVII{} program that directly makes use of the \tcode{pointer},
\tcode{const_pointer}, \tcode{reference}, \tcode{const_reference},
\tcode{rebind}, \tcode{address}, \tcode{construct}, \tcode{destroy}, or
\tcode{max_size} members of \tcode{std::allocator}, or that directly calls
\tcode{allocate} with an additional hint argument, may fail to compile.
\nodiffref
\change
Remove \tcode{raw_storage_iterator}.
\rationale
The iterator encouraged use of algorithms that might throw exceptions, but did
not return the number of elements successfully constructed that might need to
be destroyed in order to avoid leaks.
\effect
A valid \CppXVII{} program that uses this iterator class may fail to compile.
\nodiffref
\change
Remove temporary buffers API.
\rationale
The temporary buffer facility was intended to provide an efficient optimization
for small memory requests, but there is little evidence this was achieved in
practice, while requiring the user to provide their own exception-safe wrappers
to guard use of the facility in many cases.
\effect
A valid \CppXVII{} program that calls \tcode{get_temporary_buffer} or
\tcode{return_temporary_buffer} may fail to compile.
\nodiffref
\change
Remove \tcode{shared_ptr::unique}.
\rationale
The result of a call to this member function is not reliable in the presence of
multiple threads and weak pointers. The member function \tcode{use_count} is
similarly unreliable, but has a clearer contract in such cases, and remains
available for well defined use in single-threaded cases.
\effect
A valid \CppXVII{} program that calls \tcode{unique} on a \tcode{shared_ptr}
object may fail to compile.
\diffref{depr.meta.types}
\change
Remove deprecated type traits.
\rationale
The traits had unreliable or awkward interfaces. The \tcode{is_literal_type}
trait provided no way to detect which subset of constructors and member
functions of a type were declared \keyword{constexpr}. The \tcode{result_of}
trait had a surprising syntax that could not report the result of a regular
function type. It has been superseded by the \tcode{invoke_result} trait.
\effect
A valid \CppXVII{} program that relies on the \tcode{is_literal_type} or
\tcode{result_of} type traits, on the \tcode{is_literal_type_v} variable template,
or on the \tcode{result_of_t} alias template may fail to compile.
\rSec1[diff.cpp14]{\Cpp{} and ISO \CppXIV{}}
\rSec2[diff.cpp14.general]{General}
\pnum
\indextext{summary!compatibility with ISO \CppXIV{}}%
Subclause \ref{diff.cpp14} lists the differences between \Cpp{} and
ISO \CppXIV{} (ISO/IEC 14882:2014, \doccite{Programming Languages --- \Cpp{}}),
in addition to those listed above,
by the chapters of this document.
\rSec2[diff.cpp14.lex]{\ref{lex}: lexical conventions}
\diffref{lex.phases}
\indextext{trigraph sequence}%
\change
Removal of trigraph support as a required feature.
\rationale
Prevents accidental uses of trigraphs in non-raw string literals and comments.
\effect
Valid \CppXIV{} code that uses trigraphs may not be valid or may have different
semantics in this revision of \Cpp{}. Implementations may choose to
translate trigraphs as specified in \CppXIV{} if they appear outside of a raw
string literal, as part of the \impldef{mapping physical source file characters
to translation character set} mapping from physical source file characters to
the translation character set.
\diffref{lex.ppnumber}
\change
\grammarterm{pp-number} can contain \tcode{p} \grammarterm{sign} and
\tcode{P} \grammarterm{sign}.
\rationale
Necessary to enable \grammarterm{hexadecimal-floating-point-literal}s.
\effect
Valid \CppXIV{} code may fail to compile or produce different results in
this revision of \Cpp{}. Specifically, character sequences like \tcode{0p+0}
and \tcode{0e1_p+0} are three separate tokens each in \CppXIV{}, but one single token
in this revision of \Cpp{}.
For example:
\begin{codeblock}
#define F(a) b ## a
int b0p = F(0p+0); // ill-formed; equivalent to ``\tcode{int b0p = b0p + 0;}\!'' in \CppXIV{}
\end{codeblock}
\rSec2[diff.cpp14.expr]{\ref{expr}: expressions}
\diffref{expr.post.incr,expr.pre.incr}
\change
Remove increment operator with \tcode{bool} operand.
\rationale
Obsolete feature with occasionally surprising semantics.
\effect
A valid \CppXIV{} expression utilizing the increment operator on
a \tcode{bool} lvalue is ill-formed in this revision of \Cpp{}.
Note that this might occur when the lvalue has a type given by a template
parameter.
\diffref{expr.new,expr.delete}
\change
Dynamic allocation mechanism for over-aligned types.
\rationale
Simplify use of over-aligned types.
\effect
In \CppXIV{} code that uses a \grammarterm{new-expression}
to allocate an object with an over-aligned class type,
where that class has no allocation functions of its own,
\tcode{::operator new(std::size_t)}
is used to allocate the memory.
In this revision of \Cpp{},
\tcode{::operator new(std::size_t, std::align_val_t)}
is used instead.
\rSec2[diff.cpp14.dcl.dcl]{\ref{dcl.dcl}: declarations}
\diffref{dcl.stc}
\indextext{\idxcode{register} storage class}%
\change
Removal of \keyword{register} \grammarterm{storage-class-specifier}.
\rationale
Enable repurposing of deprecated keyword in future revisions of \Cpp{}.
\effect
A valid \CppXIV{} declaration utilizing the \keyword{register}
\grammarterm{storage-class-specifier} is ill-formed in this revision of \Cpp{}.
The specifier can simply be removed to retain the original meaning.
\diffref{dcl.spec.auto}
\change
\keyword{auto} deduction from \grammarterm{braced-init-list}.
\rationale
More intuitive deduction behavior.
\effect
Valid \CppXIV{} code may fail to compile or may change meaning
in this revision of \Cpp{}. For example:
\begin{codeblock}
auto x1{1}; // was \tcode{std::initializer_list<int>}, now \tcode{int}
auto x2{1, 2}; // was \tcode{std::initializer_list<int>}, now ill-formed
\end{codeblock}
\diffref{dcl.fct}
\change
Make exception specifications be part of the type system.
\rationale
Improve type-safety.
\effect
Valid \CppXIV{} code may fail to compile or change meaning in this
revision of \Cpp{}.
For example:
\begin{codeblock}
void g1() noexcept;
void g2();
template<class T> int f(T *, T *);
int x = f(g1, g2); // ill-formed; previously well-formed
\end{codeblock}
\diffref{dcl.init.aggr}
\change
Definition of an aggregate is extended
to apply to user-defined types with base classes.
\rationale
To increase convenience of aggregate initialization.
\effect
Valid \CppXIV{} code may fail to compile or produce different results in this
revision of \Cpp{}; initialization from an empty initializer list will
perform aggregate initialization instead of invoking a default constructor
for the affected types.
For example:
\begin{codeblock}
struct derived;
struct base {
friend struct derived;
private:
base();
};
struct derived : base {};
derived d1{}; // error; the code was well-formed in \CppXIV{}
derived d2; // still OK
\end{codeblock}
\rSec2[diff.cpp14.class]{\ref{class}: classes}
\diffref{class.inhctor.init}
\change
Inheriting a constructor no longer injects a constructor into the derived class.
\rationale
Better interaction with other language features.
\effect
Valid \CppXIV{} code that uses inheriting constructors may not be valid
or may have different semantics. A \grammarterm{using-declaration}
that names a constructor now makes the corresponding base class constructors
visible to initializations of the derived class
rather than declaring additional derived class constructors.
\begin{codeblock}
struct A {
template<typename T> A(T, typename T::type = 0);
A(int);
};
struct B : A {
using A::A;