Những thay đổi đột phá nào được giới thiệu trong C ++ 11?


227

Tôi biết rằng ít nhất một trong những thay đổi trong C ++ 11 sẽ khiến một số mã cũ ngừng biên dịch: việc giới thiệu explicit operator bool()trong thư viện chuẩn, thay thế các phiên bản cũ của operator void*(). Cấp, mã này sẽ bị phá vỡ có lẽ là mã không nên có hiệu lực ngay từ đầu, nhưng dù sao đó vẫn là một thay đổi vi phạm: các chương trình đã từng không còn hiệu lực.

Có bất kỳ thay đổi phá vỡ khác?


1
Loại bỏ ý nghĩa của exporttừ khóa? Tôi sẽ lấy cho tôi áo khoác.
Steve Jessop

7
Bạn biết đấy, tôi sẽ không gọi đó là việc thay đổi chuyển đổi thành bool là "thay đổi đột phá" ... giống như "thay đổi trừng phạt".
Xèo

4
Khi tất cả các thủ tục giấy tờ cần thiết để tạo ra một liên minh như vậy chỉ chờ được đóng dấu cao su, chắc chắn, tại sao không?
Dennis Zickefoose

3
@Xeo: mystream.good()không giống như bool(mystream)? good()là đúng nếu không có cờ nào được đặt. bool(mystream)vẫn sai nếu chỉ eofbitđược đặt. !mystream.fail()sẽ là tương đương chính xác.
R. Martinho Fernandes

2
Người điều hành lưu ý : " Vui lòng giữ bình luận về chủ đề với câu hỏi hoặc câu trả lời. Khi thảo luận về câu hỏi hoặc câu trả lời, cuộc thảo luận chỉ nên nói về câu hỏi hoặc câu trả lời. Tranh luận, nói chung không mang tính xây dựng cho Stack Overflow. Đối kháng chắc chắn là không. "
Tim Post

Câu trả lời:


178

FDIS có một phần không tương thích, tại phụ lục C.2"C ++ và ISO C ++ 2003".

Tóm tắt, diễn giải FDIS ở đây, để làm cho nó (tốt hơn) phù hợp như một câu trả lời SO. Tôi đã thêm một số ví dụ của riêng tôi để minh họa sự khác biệt.

Có một vài sự không tương thích liên quan đến thư viện mà tôi không biết chính xác ý nghĩa của nó, vì vậy tôi để những thứ đó cho người khác giải thích.

Ngôn ngữ cốt lõi


#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"

#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .

Các từ khóa mới: alignas, alignof, char16_t, char32_t, constexpr, dectype, noexcept, nullptr, static_assert và thread_local


Một số chữ nguyên nhất định lớn hơn có thể được biểu thị bằng dài có thể thay đổi từ loại số nguyên không dấu sang chữ ký dài.


Mã C ++ 2003 hợp lệ sử dụng phép chia số nguyên làm tròn kết quả về 0 hoặc hướng tới vô cực âm, trong khi C ++ 0x luôn làm tròn kết quả về 0.

(thừa nhận không thực sự là một vấn đề tương thích cho hầu hết mọi người).


Mã C ++ 2003 hợp lệ sử dụng từ khóa autolàm công cụ xác định lớp lưu trữ có thể không hợp lệ trong C ++ 0x.


Chuyển đổi hẹp gây ra sự không tương thích với C ++ 03. Ví dụ: đoạn mã sau hợp lệ trong C ++ 2003 nhưng không hợp lệ trong Tiêu chuẩn quốc tế này vì double to int là một chuyển đổi thu hẹp:

int x[] = { 2.0 };

Các hàm thành viên đặc biệt được khai báo ngầm định được định nghĩa là đã bị xóa khi định nghĩa ngầm sẽ không được định dạng.

Một chương trình C ++ 2003 hợp lệ sử dụng một trong các hàm thành viên đặc biệt này trong bối cảnh không yêu cầu định nghĩa (ví dụ: trong một biểu hiện không có khả năng được đánh giá) trở nên không rõ ràng.

Ví dụ của tôi:

struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }

Thủ thuật sizeof như vậy đã được một số SFINAE sử dụng và cần phải thay đổi ngay bây giờ :)


Các hàm hủy do người dùng khai báo có một đặc tả ngoại lệ ngầm định.

Ví dụ của tôi:

struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }

Mã này gọi terminatetrong C ++ 0x, nhưng không có trong C ++ 03. Bởi vì đặc tả ngoại lệ ngầm định A::~Atrong C ++ 0x là noexcept(true).


Một khai báo C ++ 2003 hợp lệ có chứa exportkhông đúng định dạng trong C ++ 0x.


Một biểu thức C ++ 2003 hợp lệ có chứa >theo sau bởi một biểu thức khác >hiện có thể được coi là đóng hai mẫu.

Trong C ++ 03, >>sẽ luôn là mã thông báo toán tử thay đổi.


Cho phép các cuộc gọi phụ thuộc của các chức năng với liên kết nội bộ.

Ví dụ của tôi:

static void f(int) { }
void f(long) { }

template<typename T>
void g(T t) { f(t); }

int main() { g(0); }

Trong C ++ 03, cuộc gọi này f(long), nhưng trong C ++ 0x, cuộc gọi này f(int). Cần lưu ý rằng trong cả C ++ 03 và C ++ 0x, các cuộc gọi sau f(B)(bối cảnh khởi tạo vẫn chỉ xem xét các khai báo liên kết ngoài).

struct B { };
struct A : B { };

template<typename T>
void g(T t) { f(t); }

static void f(A) { }
void f(B) { }

int main() { A a; g(a); }

Sự phù hợp tốt hơn f(A)không được thực hiện, bởi vì nó không có liên kết bên ngoài.


Thay đổi thư viện

Mã C ++ 2003 hợp lệ sử dụng bất kỳ số nhận dạng nào được thêm vào thư viện chuẩn C ++ của C ++ 0x có thể không biên dịch hoặc tạo ra các kết quả khác nhau trong Tiêu chuẩn quốc tế này.


Mã C ++ 2003 hợp lệ mà #includescác tiêu đề có tên của các tiêu đề thư viện chuẩn C ++ 0x mới có thể không hợp lệ trong Tiêu chuẩn quốc tế này.


Mã C ++ 2003 hợp lệ đã được biên dịch dự kiến ​​trao đổi <algorithm>có thể phải thay vào đó bao gồm<utility>


Không gian tên toàn cầu posixhiện được dành riêng cho tiêu chuẩn hóa.


Hợp lệ C ++ 2003 mã mà định nghĩa override, final, carries_dependency, hoặc noreturnnhư macro là không hợp lệ trong C ++ 0x.


"Cho phép các cuộc gọi phụ thuộc của các chức năng với liên kết nội bộ." Bạn có thể vui lòng giải thích về sự khác biệt giữa hai ví dụ của bạn? Tôi rõ ràng đang thiếu một cái gì đó.
Dennis Zickefoose

@Dennis thay đổi được giới thiệu bởi open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#561 . Mặc dù họ không bình luận về thực tế, "bối cảnh khởi tạo" vẫn chỉ bao gồm "tập hợp các khai báo có liên kết bên ngoài được khai báo trước thời điểm khởi tạo chuyên môn hóa mẫu trong cùng một đơn vị dịch thuật". Vì vậy, sự thay đổi họ thực hiện chỉ ảnh hưởng đến việc tra cứu trong bối cảnh định nghĩa.
Julian Schaub - litb

Trong ví dụ đầu tiên của tôi được đưa ra, hàm liên kết nội bộ có thể nhìn thấy và được tìm thấy trong ngữ cảnh định nghĩa của mẫu. Trong ví dụ thứ hai của tôi, hàm liên kết nội bộ sẽ cần phải là một phần của bối cảnh khởi tạo được tìm thấy. Nhưng vì nó không phải, nó không thể được tìm thấy.
Julian Schaub - litb

Ngẫu nhiên, tôi nghĩ trường hợp duy nhất an toàn cho bối cảnh định nghĩa mẫu để tìm một hàm có liên kết bên trong là khi chuyên môn hóa mẫu hàm chỉ được khởi tạo rõ ràng ngay lập tức trong một TU (trong đó mẫu được xác định) và tất cả các TU khác đều dựa vào tức thời rõ ràng. Trong tất cả các trường hợp khác (trong đó các TU khác sẽ khởi tạo chính họ chuyên môn hóa), bạn sẽ vi phạm ODR bằng cách định nghĩa mẫu sử dụng chức năng (liên kết nội bộ) khác nhau mỗi lần.
Julian Schaub - litb

Vì vậy, tôi không chắc tại sao họ giữ hạn chế trong bối cảnh khởi tạo - sẽ chỉ có một khởi tạo (rõ ràng) và việc khởi tạo đó sẽ sử dụng các hàm liên kết nội bộ được tìm thấy trong ngữ cảnh khởi tạo của TU khởi tạo. Cũng giống như nó sẽ cho bối cảnh định nghĩa. Ngẫu nhiên, tôi nghĩ rằng nếu chúng ta vẫn còn export, thì tôi nghĩ rằng các TU khác sẽ không cần phải dựa vào việc khởi tạo rõ ràng, nhưng có thể khởi tạo chính bản thân mẫu. Sau đó, nó sẽ làm cho một sự khác biệt cho dù các chức năng liên kết nội bộ có thể nhìn thấy trong bối cảnh khởi tạo hay không.
Julian Schaub - litb

28

Ý nghĩa của từ khóa tự động đã thay đổi.


9
Nếu bạn đã sử dụng autotừ khóa, có gì đó rất sai với mã của bạn. Tại sao trên trái đất bạn sẽ sử dụng nó?
Elazar Leibovich

Đó không phải là một sự thay đổi đột phá . Mỗi lần sử dụng C ++ 03 autohợp lệ vẫn còn hiệu lực trong C ++ 11.
Drew Dormann

11
@DrewDormann int main() { auto int i = 0; return i; }hoàn toàn hợp lệ C ++ 03, nhưng lỗi cú pháp trong C ++ 11. Cảnh báo duy nhất tôi có thể nhận được trình biên dịch để cung cấp cho nó trong chế độ C ++ 03 là cảnh báo về khả năng tương thích.

24

Phá vỡ sự thay đổi?

Vâng, đối với một điều, nếu bạn sử dụng decltype, constexpr, nullptr, vv như định danh sau đó bạn có thể gặp rắc rối ...


21

Một số điểm không tương thích cốt lõi không nằm trong phần không tương thích:


C ++ 0x coi tên lớp được chèn dưới dạng mẫu, nếu tên được truyền dưới dạng đối số cho tham số mẫu mẫu và dưới dạng loại nếu nó được truyền cho tham số loại mẫu.

Mã C ++ 03 hợp lệ có thể hoạt động khác đi nếu nó dựa vào tên lớp được chèn để luôn là một kiểu trong các tình huống này. Mã ví dụ được lấy từ PR clang của tôi

template<template<typename> class X>
struct M { };

template<template<typename> class X>
void g(int = 0); // #1

template<typename T>
void g(long = 0); // #2

template<typename T>
struct A {
  void f() {
    g<A>(); /* is ambiguous in C++0x */
    g<A>(1); /* should choose #1 in C++0x */
  }
};

void h() {
  A<int> a;
  a.f();
}

Trong C ++ 03, mã gọi lần thứ hai gcả hai lần.


C ++ 0x làm cho một số tên phụ thuộc trong C ++ 03 trở thành không phụ thuộc. Và yêu cầu tra cứu tên cho các tên đủ điều kiện không phụ thuộc tham chiếu đến các thành viên của mẫu lớp hiện tại để được lặp lại tại thời điểm khởi tạo và yêu cầu xác minh rằng các tên này tra cứu giống như được thực hiện trong bối cảnh định nghĩa mẫu.

Mã C ++ 03 hợp lệ phụ thuộc vào quy tắc thống trị bây giờ có thể không được biên dịch nữa vì thay đổi này.

Thí dụ:

struct B { void f(); };

template<typename T>
struct A : virtual B { void f(); };

template<typename T>
struct C : virtual B, A<T> {
  void g() { this->f(); }
};

int main() { C<int> c; c.g(); }

Mã C ++ 03 hợp lệ này mà các cuộc gọi A<int>::fkhông hợp lệ trong C ++ 0x, vì việc tra cứu tên khi khởi tạo sẽ tìm thấy A<int>::ftrái ngược với B::f, gây ra xung đột với tra cứu định nghĩa.

Tại thời điểm này, không rõ liệu đó có phải là một khiếm khuyết trong FDIS hay không. Ủy ban nhận thức được điều này và sẽ đánh giá tình hình.


Một khai báo sử dụng trong đó phần cuối giống như mã định danh trong phần cuối của vòng loại trong tên đủ điều kiện biểu thị một lớp cơ sở, sử dụng khai báo bây giờ đặt tên cho hàm tạo, thay vì các thành viên có tên đó.

Thí dụ:

struct A { protected: int B; };
typedef A B;

struct C : B {
  // inheriting constructor, instead of bringing A::B into scope
  using B::B;
};

int main() { C c; c.B = 0; }

Mã ví dụ trên được hình thành tốt trong C ++ 03, nhưng không được định dạng trong C ++ 0x, vì A::Bvẫn không thể truy cập được main.


14

Lỗi khai thác dòng được xử lý khác nhau.

Thí dụ

#include <sstream>
#include <cassert>

int main()
{
   std::stringstream ss;
   ss << '!';
   
   int x = -1;
   
   assert(!(ss >> x)); // C++03 and C++11
   assert(x == -1);    // C++03
   assert(x == 0);     // C++11
}

Thay đổi đề xuất

http://www.open-std.org/jtc1/sc22/wg21/docs/ con / 2011 / n3246.html # 23

Tiêu chuẩn tham khảo

[C++03: 22.2.2.1.2/11]: Kết quả của quá trình xử lý giai đoạn 2 có thể là một trong

  • Một chuỗi ký tự đã được tích lũy trong giai đoạn 2 được chuyển đổi (theo quy tắc của scanf) thành giá trị của loại val. Giá trị này được lưu trữ trong valios_base::goodbitđược lưu trữ trong err.
  • Chuỗi ký tự được tích lũy trong giai đoạn 2 sẽ gây ra lỗi scanfbáo cáo đầu vào. ios_base::failbitđược giao cho err. [ed: Không có gì được lưu trữ trong val.]

[C++11: 22.4.2.1.2/3]: [..] Giá trị số được lưu trữ có thể là một trong:

  • bằng không, nếu chức năng chuyển đổi không chuyển đổi toàn bộ trường . ios_base::failbitđược giao cho err.
  • giá trị đại diện tích cực nhất, nếu trường đại diện cho một giá trị quá lớn dương được thể hiện trong val. ios_base::failbitđược giao cho err.
  • giá trị đại diện tiêu cực nhất hoặc bằng 0 đối với loại số nguyên không dấu, nếu trường đại diện cho một giá trị quá lớn âm được thể hiện trong val. ios_base::failbitđược giao cho err.
  • giá trị chuyển đổi, nếu không.

Giá trị số kết quả được lưu trữ trong val.

Triển khai

  • GCC 4.8 đầu ra chính xác cho C ++ 11 :

    Khẳng định `x == -1 'không thành công

  • GCC 4.5-4.8 tất cả đầu ra cho C ++ 03 sau đây, có vẻ như là một lỗi:

    Khẳng định `x == -1 'không thành công

  • Visual C ++ 2008 Express xuất ra chính xác cho C ++ 03:

    Khẳng định không thành công: x == 0

  • Visual C ++ 2012 Express xuất ra không chính xác cho C ++ 11, đây có vẻ là một vấn đề về tình trạng thực hiện:

    Khẳng định không thành công: x == 0


13

Làm thế nào để giới thiệu các toán tử chuyển đổi rõ ràng là một thay đổi đột phá? Phiên bản cũ vẫn sẽ vẫn "hợp lệ" như trước.

Đúng, thay đổi từ operator void*() constthành explicit operator bool() constsẽ là một thay đổi đột phá, nhưng chỉ khi nó được sử dụng theo cách sai trong và ngoài chính nó. Mã phù hợp sẽ không bị phá vỡ.

Bây giờ, một thay đổi đột phá khác là cấm thu hẹp chuyển đổi trong quá trình khởi tạo tổng hợp :

int a[] = { 1.0 }; // error

Chỉnh sửa : Chỉ cần nhớ, std::identity<T>sẽ bị xóa trong C ++ 0x (xem ghi chú). Đó là một cấu trúc thuận tiện để làm cho các loại phụ thuộc. Vì struct thực sự không làm được gì nhiều, nên điều này sẽ khắc phục nó:

template<class T>
struct identity{
  typedef T type;
};

Nếu các đối tượng thư viện chuẩn có các chuyển đổi rõ ràng được thêm vào, thì các chuyển đổi ngầm định hiện tại có thể ngừng hoạt động. Nhưng tôi không thể tưởng tượng một kịch bản trong đó việc chuyển đổi sẽ không hợp lệ và làm điều gì đó hữu ích.
Dennis Zickefoose

Giới thiệu là một thay đổi đột phá vì nó sẽ thay thế hiện tại operator void*.
R. Martinho Fernandes

@Dennis: Aaah, giờ tôi hiểu ý của @Martinho. Nhưng nó sẽ chỉ là một sự thay đổi đột phá nếu mọi người sử dụng nó ngoài mục đích.
Xèo

"nhưng chỉ khi nó được sử dụng theo cách sai và tự nó" - bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }Không có gì thực sự sai với điều đó trong C ++ 03, nhưng nó đã trở thành một lỗi trong C ++ 11. (Lưu ý: GCC 4.9 vẫn có operator void*() constở đây, đó là lý do tại sao nó chấp nhận mã ở chế độ C ++ 11.)

std::identity<T>không bị xóa trong C ++ 11, vì nó không phải là một phần của C ++ 03. Nó đã tồn tại một thời gian ngắn trong dự thảo cho C ++ 11 và đã bị xóa khỏi dự thảo trước khi tiêu chuẩn hóa.
Howard Hinnant


7

Đã có rất nhiều cuộc thảo luận về việc di chuyển ngầm phá vỡ khả năng tương thích ngược

( một trang cũ hơn với các cuộc thảo luận có liên quan )

Nếu bạn đọc xuống các bình luận, trở lại di chuyển ngầm cũng là một thay đổi đột phá.


Kết quả của những cuộc thảo luận là nó đã bị loại bỏ trong hầu hết các trường hợp. Có bất kỳ vấn đề với những gì còn lại?
Dennis Zickefoose

@Dennis: Vâng. Câu hỏi của bạn đã được hỏi, trả lời và tranh luận cho đến chết trên trang theo dõi này
Ben Voigt

Ahh, trang di động không hiển thị các bình luận. Dù bằng cách nào, đó là liên kết hữu ích hơn nhiều ... Những điều kỳ lạ trong lịch sử của quá trình tiêu chuẩn hóa không liên quan (trừ khi bạn đang sử dụng MSVC, mà tôi tin rằng sử dụng bản nháp đầu tiên đó).
Dennis Zickefoose

@Dennis: Tôi nghĩ bạn đúng. Di chuyển các liên kết xung quanh một số trong câu trả lời của tôi.
Ben Voigt

Đáng buồn thay, cpp-next.com không còn tồn tại nữa. Để tham khảo trong tương lai, đây là các trang được lưu bởi web.archive.org: di chuyển ngầm phá vỡ tính tương thích ngượcmột trang cũ hơn với các cuộc thảo luận có liên quan .
Max Truxa

6
struct x {
   x(int) {}
};

void f(auto x = 3) { }

int main() {
   f();
}

C ++ 03: hợp lệ.

C ++ 0x: error: parameter declared 'auto'


2
@Xeo: Mã hợp lệ trong C ++ 03. Đó là một tham số với loại struct xvà không có tên.
Ben Voigt

Tôi đã hy vọng để bắt được một ai đó. Tôi chỉ ước @Xeo không nhanh chóng xóa bình luận của anh ấy, vì tôi đã không được đọc nó!
Các cuộc đua nhẹ nhàng trong quỹ đạo

@Xeo: Không cần đào sâu về ngữ pháp, tôi chắc chắn tự động không phải là một từ khóa hợp lệ ở đó. Nếu đúng như vậy, nó có thể sẽ hoạt động như bạn mong đợi, nhưng điều đó có lẽ thực sự khó xác định đúng.
Dennis Zickefoose

Hãy nói rằng bạn đã bắt được tôi. Nó thực sự bỏ qua các cấu trúc. :)
Xeo

@Tomalek: Xeo đã chỉ ra rằng C ++ 03 không có int ẩn.
Ben Voigt

-4

Đặc điểm ngôn ngữ

  1. Khởi tạo thống nhất và chung bằng {}
  2. Tự động
  3. Phòng chống hẹp
  4. constexpr
  5. Phạm vi dựa trên vòng lặp
  6. nullptr
  7. lớp enum
  8. static_assert
  9. std :: initizer_list
  10. Tài liệu tham khảo Rvalue (di chuyển ngữ nghĩa)
  11. >>
  12. Chiên
  13. Mẫu biến thể
  14. Loại và bí danh mẫu
  15. Ký tự Unicode
  16. kiểu số nguyên dài
  17. alignas và alignof
  18. sự từ chối
  19. Chuỗi ký tự thô
  20. POD tổng quát
  21. Công đoàn tổng quát
  22. Các lớp cục bộ làm đối số mẫu
  23. Cú pháp trả về kiểu hậu tố
  24. [[carry_dependency]] và [[noreturn]]
  25. công cụ xác định
  26. toán tử không chấp nhận.
  27. Các tính năng của C99:
    • loại tích phân mở rộng
    • nối chuỗi hẹp / rộng
    • _ _ STDC_HOSTED _ _
    • _Pragma (X)
    • macro vararg và đối số macro trống
  28. _ _ func _ _
  29. Không gian tên nội tuyến
  30. Đại biểu xây dựng
  31. Khởi tạo thành viên trong lớp
  32. mặc định và xóa
  33. Toán tử chuyển đổi rõ ràng
  34. Chữ do người dùng định nghĩa
  35. Mẫu bên ngoài
  36. Đối số mẫu mặc định cho các mẫu hàm
  37. Kế thừa các nhà xây dựng
  38. ghi đè và cuối cùng
  39. Đơn giản hơn và quy tắc SFINAE tổng quát hơn
  40. Mô hình bộ nhớ
  41. chủ đề

Thành phần thư viện chuẩn

  1. initizer_list cho container
  2. Di chuyển ngữ nghĩa cho container
  3. chuyển tiếp
  4. Thùng băm
    • unordered_map
    • không có thứ tự_multimap
    • unordered_set
    • không có thứ tự_multiset
  5. Con trỏ quản lý tài nguyên
    • độc đáo
    • đã chia sẻ
    • yếu_ptr
  6. Hỗ trợ đồng thời
    • chủ đề
    • đột biến
    • ổ khóa
    • biến điều kiện
  7. Hỗ trợ đồng thời cấp cao hơn
    • đóng gói_thread
    • Tương lai
    • lời hứa
    • không đồng bộ
  8. bộ
  9. regex
  10. Số ngẫu nhiên
    • thống nhất_int_distribution
    • phân phối bình thường
    • ngẫu nhiên
    • Vân vân.
  11. Tên loại số nguyên, chẳng hạn như int16_t, uint32_t và int_fast64_t
  12. mảng
  13. Sao chép và suy nghĩ lại ngoại lệ
  14. lỗi hệ thống
  15. hoạt động emplace () cho container
  16. hàm constexpr
  17. Sử dụng có hệ thống các chức năng không ngoại lệ
  18. chức năng và ràng buộc
  19. Chuyển đổi chuỗi thành giá trị số
  20. Phân bổ phạm vi
  21. Kiểu tính trạng
  22. Tiện ích thời gian: thời lượng và time_point
  23. tỉ lệ
  24. quick_exit
  25. Nhiều thuật toán hơn, chẳng hạn như move (), copy_if () và is_sort ()
  26. Thu gom rác ABI
  27. nguyên tử

Tính năng không dùng nữa

  1. Tạo trình xây dựng sao chép và gán sao chép cho một lớp với hàm hủy.
  2. Gán một chuỗi ký tự cho một char *.
  3. Đặc tả ngoại lệ C ++ 98
    • không được chấp nhận_handler
    • set_unazed
    • get_unazed
    • bất ngờ
  4. Các đối tượng chức năng và các chức năng liên quan
  5. tự động
  6. Đăng ký
  7. ++ trên một bool
  8. xuất khẩu
  9. Diễn viên kiểu C

3
Điều này không trả lời câu hỏi.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.