Cờ để bật cảnh báo g ++ chi tiết và kỹ lưỡng


122

Thông thường trong C dưới gcc, tôi sẽ bắt đầu với tập hợp các cờ cảnh báo sau (được tổng hợp từ nhiều nguồn):

-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \
-Wfloat-equal -pedantic -ansi

Tôi sẽ xây dựng (ít nhất là các phiên bản gỡ lỗi của tôi) với bộ cảnh báo này và sửa mọi thứ tôi có thể có thể (thường là mọi thứ), và sau đó chỉ xóa cờ nếu chúng không liên quan hoặc không thể sửa được (hầu như không bao giờ xảy ra trường hợp này). Đôi khi, tôi cũng sẽ thêm vào -Werrornếu tôi phải rời đi trong khi biên dịch.

Tôi mới bắt đầu học C ++ (vâng, tôi đi sau 15 năm so với thời đại) và tôi muốn bắt đầu ngay từ đầu.

Câu hỏi của tôi là: Có ai đó có một bộ cờ cảnh báo hoàn chỉnh tương tự được biên dịch trước cho C ++ g++không? (Tôi biết nhiều người trong số họ sẽ giống nhau.)


69
Có gì nhu cầu gcc (vì nó quyết định cách trắng trợn dối trá về -Wall) là một -Wbloody_everythinglá cờ :-)
paxdiablo

Bạn có thể đánh dấu câu hỏi của mình là một bản dupe nhưng bạn cũng có thể đặt bản chỉnh sửa cuối cùng của mình làm câu trả lời vì bạn đã thực sự trả lời câu hỏi của mình. Và tôi rất vui khi
ủng hộ

4
OP và @paxdiablo: GCC đã liên tục từ chối loại điều này, nhưng nó có sẵn trong Clang thông qua -Weverything. Tôi đã đọc rằng ngay cả các nhà phát triển Clang ++ cũng hơi lo ngại về việc người dùng bật nó lên; rõ ràng nó chỉ dành cho mục đích phát triển nội bộ. Tuy nhiên, điều này không có ý nghĩa gì vì bật -Weverythingcó lẽ là cách tốt nhất có thể để khám phá các cảnh báo có thể hữu ích mà bạn chưa biết trước đây.
Kyle Strand

1
OP và @paxdiablo Bây giờ có một cách để tìm ra danh sách đầy đủ các cảnh báo cho một phiên bản GCC nhất định: github.com/barro/compiler-warnings
Kyle Strand

Câu trả lời:


138

Tôi đã xem qua và nhận thấy tập hợp tối thiểu bao gồm sẽ nhận được mức cảnh báo tối đa. Sau đó, tôi đã xóa khỏi danh sách đó tập hợp các cảnh báo mà tôi cảm thấy không thực sự chỉ ra điều gì đó tồi tệ đang xảy ra, hoặc có quá nhiều kết quả dương tính giả được sử dụng trong một bản dựng thực. Tôi nhận xét là tại sao mỗi cái tôi đã loại trừ đều bị loại trừ. Đây là bộ cảnh báo đề xuất cuối cùng của tôi:

-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused

Các cảnh báo đáng nghi vấn hiện có:

  • Tôi bao gồm -Wno-unusedvì tôi thường có các biến mà tôi biết tôi sẽ sử dụng sau này, nhưng chưa có chức năng được viết cho. Xóa cảnh báo về điều đó cho phép tôi viết theo phong cách ưa thích của tôi là thỉnh thoảng trì hoãn việc thực hiện mọi thứ. Sẽ rất hữu ích nếu thỉnh thoảng tắt tính năng đó để đảm bảo không có gì lọt qua các khe nứt.

  • -Wdisabled-optimizationcó vẻ như một cài đặt ưu tiên người dùng mạnh mẽ. Tôi vừa thêm cái này vào bản dựng của mình (chỉ dành cho các bản dựng được tối ưu hóa vì những lý do rõ ràng) và nó không xuất hiện bất cứ điều gì, vì vậy nó dường như không phải là một cảnh báo đặc biệt về trò chuyện, ít nhất là đối với cách tôi viết mã. Tôi bao gồm nó (mặc dù mã kích hoạt cảnh báo này không nhất thiết là sai) bởi vì tôi tin vào việc làm việc với các công cụ của mình thay vì chống lại chúng. Nếu gcc nói với tôi rằng nó không thể tối ưu hóa mã theo cách tôi đã viết nó, thì tôi nên xem xét việc viết lại nó. Tôi nghi ngờ rằng mã kích hoạt cảnh báo này có thể được hưởng lợi từ việc trở nên mô-đun hơn, vì vậy mặc dù mã không sai về mặt kỹ thuật (có thể), nhưng về mặt phong cách thì nó có thể là như vậy.

  • -Wfloat-equalcảnh báo so sánh bình đẳng an toàn (đặc biệt, so sánh với giá trị không được tính toán là -1). Một ví dụ trong mã của tôi mà tôi sử dụng điều này là tôi có một vectơ float. Tôi xem qua vectơ này và có một số phần tử tôi chưa thể đánh giá chúng nên là gì, vì vậy tôi đặt chúng thành -1.0f (vì bài toán của tôi chỉ sử dụng số dương, -1 nằm ngoài miền). Sau đó, tôi sẽ xem xét và cập nhật các giá trị -1.0f. Nó không dễ dàng cho mình một phương pháp hoạt động khác. Tôi nghi ngờ rằng hầu hết mọi người không gặp vấn đề này và việc so sánh một số chính xác trong dấu phẩy động có thể là một lỗi, vì vậy tôi đưa nó vào danh sách mặc định.

  • -Wold-style-castcó rất nhiều sai lệch trong mã thư viện mà tôi đang sử dụng. Đặc biệt, nhóm hàm htonl được sử dụng trong mạng, cũng như triển khai mã hóa Rijndael (AES) mà tôi đang sử dụng có các phôi kiểu cũ mà nó cảnh báo cho tôi. Tôi định thay thế cả hai điều này, nhưng tôi không chắc liệu có điều gì khác trong mã của tôi mà nó sẽ phàn nàn hay không. Tuy nhiên, hầu hết người dùng có lẽ nên bật tính năng này theo mặc định.

  • -Wsign-conversionlà một trong những khó khăn (và gần như không lọt vào danh sách). Việc bật tính năng này trong mã của tôi đã tạo ra một lượng lớn cảnh báo (hơn 100). Hầu như tất cả họ đều vô tội. Tuy nhiên, tôi đã cẩn thận sử dụng các số nguyên có dấu ở bất cứ nơi nào tôi không chắc chắn, mặc dù đối với miền có vấn đề cụ thể của tôi, tôi thường sẽ tăng hiệu quả một chút khi sử dụng các giá trị không có dấu do số lượng lớn phép chia số nguyên mà tôi thực hiện. Tôi đã hy sinh hiệu quả này vì tôi lo lắng về việc vô tình chuyển một số nguyên có dấu thành một số không có dấu và sau đó chia (không an toàn, không giống như cộng, trừ và nhân). Việc bật cảnh báo này cho phép tôi thay đổi một cách an toàn hầu hết các biến của mình thành các loại không dấu và thêm một vài phôi ở một số nơi khác. Nó hiện hơi khó sử dụng vì cảnh báo không thông minh. Ví dụ, nếu bạn làmunsigned short + (integral constant expression), kết quả đó được thăng cấp ngầm thành int. Sau đó, nó cảnh báo về sự cố dấu hiệu tiềm ẩn nếu bạn gán giá trị đó cho unsignedhoặc unsigned short, mặc dù nó an toàn. Đây chắc chắn là cảnh báo tùy chọn nhất cho hầu hết mọi người dùng.

  • -Wsign-promo: xem -Wsign-conversion.

  • -Wswitch-defaultdường như vô nghĩa (bạn không phải lúc nào cũng muốn có một trường hợp mặc định nếu bạn đã liệt kê tất cả các khả năng một cách rõ ràng). Tuy nhiên, bật cảnh báo này có thể thực thi một điều gì đó có lẽ là một ý kiến ​​hay. Đối với trường hợp bạn muốn bỏ qua mọi thứ ngoại trừ các khả năng được liệt kê (nhưng các số khác có thể xảy ra), thì hãy đặtdefault: break;để làm cho nó rõ ràng. Nếu bạn liệt kê rõ ràng tất cả các khả năng, thì việc bật cảnh báo này sẽ giúp đảm bảo rằng bạn đặt một cái gì đó như khẳng định (sai) để đảm bảo rằng bạn đã thực sự bao gồm tất cả các tùy chọn có thể. Nó cho phép bạn hiểu rõ ràng lĩnh vực của vấn đề là gì và thực thi điều đó theo chương trình. Tuy nhiên, bạn sẽ phải cẩn thận khi chỉ dán khẳng định (sai) ở khắp mọi nơi. Tốt hơn là không làm gì với trường hợp mặc định, nhưng như thường lệ với khẳng định, nó sẽ không hoạt động trong các bản phát hành. Nói cách khác, bạn không thể dựa vào nó để xác thực các số mà bạn nhận được, chẳng hạn như kết nối mạng hoặc cơ sở dữ liệu mà bạn không có quyền kiểm soát tuyệt đối. Ngoại lệ hoặc quay lại sớm là cách tốt nhất để xử lý điều đó (nhưng vẫn yêu cầu bạn phải có trường hợp mặc định!).

  • -Werrorlà một điều quan trọng đối với tôi. Khi biên dịch một lượng lớn mã trong một bản dựng đa luồng với nhiều mục tiêu, rất dễ để cảnh báo bỏ qua. Việc chuyển cảnh báo thành lỗi đảm bảo rằng tôi nhận thấy chúng.

Sau đó, có một tập hợp các cảnh báo không có trong danh sách trên vì tôi không thấy chúng hữu ích. Đây là những cảnh báo và nhận xét của tôi về lý do tại sao tôi không đưa chúng vào danh sách mặc định:

Cảnh báo không có:

  • -Wabilà không cần thiết vì tôi không kết hợp các tệp nhị phân từ các trình biên dịch khác nhau. Tôi đã thử biên dịch với nó dù sao, và nó không kích hoạt, vì vậy nó có vẻ không cần quá dài dòng.

  • -Waggregate-returnkhông phải là thứ mà tôi coi là lỗi. Ví dụ, nó kích hoạt khi sử dụng vòng lặp for dựa trên phạm vi trên một vectơ của các lớp. Việc tối ưu hóa giá trị trả lại nên quan tâm đến bất kỳ tác động tiêu cực nào của việc này.

  • -Wconversionkích hoạt trên mã này: short n = 0; n += 2;Việc chuyển đổi ngầm thành int gây ra cảnh báo khi nó được chuyển đổi trở lại loại đích.

  • -Weffc++bao gồm cảnh báo nếu tất cả các thành viên dữ liệu không được khởi tạo trong danh sách trình khởi tạo. Tôi cố ý không làm điều này trong nhiều trường hợp, vì vậy tập hợp các cảnh báo quá lộn xộn để hữu ích. Tuy nhiên, sẽ rất hữu ích khi bật lại một lần và quét các cảnh báo khác (chẳng hạn như trình hủy không ảo của các lớp cơ sở). Điều này sẽ hữu ích hơn khi là một tập hợp các cảnh báo (như -Wall) thay vì một cảnh báo riêng lẻ.

  • -Winlinevắng mặt vì tôi không sử dụng từ khóa nội dòng cho mục đích tối ưu hóa, chỉ để xác định các hàm nội tuyến trong tiêu đề. Tôi không quan tâm nếu trình tối ưu hóa thực sự nội dòng nó. Cảnh báo này cũng phàn nàn nếu nó không thể nội dòng một hàm được khai báo trong thân lớp (chẳng hạn như hàm hủy ảo trống).

  • -Winvalid-pch bị thiếu vì tôi không sử dụng tiêu đề được biên dịch trước.

  • -Wmissing-format-attributekhông được sử dụng vì tôi không sử dụng phần mở rộng gnu. Tương tự cho -Wsuggest-attributevà một số người khác

  • Khả năng đáng chú ý vì sự vắng mặt của nó là -Wno-long-long, điều mà tôi không cần. Tôi biên dịch với -std=c++0x( -std=c++11trong GCC 4.7), bao gồm long longcác kiểu số nguyên. Những người bị mắc kẹt trở lại C ++ 98 / C ++ 03 có thể xem xét thêm loại trừ đó khỏi danh sách cảnh báo.

  • -Wnormalized=nfc đã là tùy chọn mặc định và có vẻ là tùy chọn tốt nhất.

  • -Wpaddedđược bật thỉnh thoảng để tối ưu hóa bố cục của các lớp, nhưng nó không được bật vì không phải tất cả các lớp đều có đủ phần tử để xóa phần đệm ở cuối. Về lý thuyết, tôi có thể nhận được một số biến bổ sung 'miễn phí', nhưng không đáng để cố gắng duy trì điều đó (nếu quy mô lớp học của tôi thay đổi, thật không dễ dàng để loại bỏ những biến miễn phí trước đó).

  • -Wstack-protector không được sử dụng bởi vì tôi không sử dụng -fstack-protector

  • -Wstrict-aliasing=3được bật bởi -Wallvà là mức chính xác nhất, nhưng có vẻ như mức 1 và 2 đưa ra nhiều cảnh báo hơn. Về lý thuyết, mức thấp hơn là một cảnh báo 'mạnh hơn', nhưng nó phải trả giá bằng nhiều dương tính giả hơn. Mã kiểm tra của riêng tôi được biên dịch rõ ràng theo cả 3 cấp độ.

  • -Wswitch-enumkhông phải là hành vi mà tôi muốn. Tôi không muốn xử lý mọi câu lệnh switch một cách rõ ràng. Sẽ rất hữu ích nếu ngôn ngữ có một số cơ chế để kích hoạt điều này trên các câu lệnh chuyển đổi được chỉ định (để đảm bảo rằng các thay đổi trong tương lai đối với enum được xử lý ở mọi nơi mà chúng cần), nhưng nó quá mức cần thiết đối với cài đặt "tất cả hoặc không có gì".

  • -Wunsafe-loop-optimizationsgây ra quá nhiều cảnh báo giả. Có thể hữu ích nếu áp dụng phương pháp này định kỳ và xác minh kết quả theo cách thủ công. Ví dụ: nó tạo ra cảnh báo này trong mã của tôi khi tôi lặp qua tất cả các phần tử trong một vectơ để áp dụng một tập hợp các hàm cho chúng (sử dụng vòng lặp for dựa trên phạm vi). Nó cũng cảnh báo cho phương thức khởi tạo của một mảng const của chuỗi const std :: (trong đó đây không phải là vòng lặp trong mã người dùng).

  • -Wzero-as-null-pointer-constant-Wuseless-castlà những cảnh báo chỉ dành cho GCC-4.7 mà tôi sẽ thêm vào khi chuyển sang GCC 4.7.

Tôi đã gửi một số báo cáo lỗi / yêu cầu nâng cao tại gcc là kết quả của một số nghiên cứu này, vì vậy hy vọng cuối cùng tôi sẽ có thể thêm nhiều cảnh báo từ danh sách "không bao gồm" vào danh sách "bao gồm" . Danh sách này bao gồm tất cả các cảnh báo được đề cập trong chủ đề này (cộng với tôi nghĩ thêm một số cảnh báo). Nhiều cảnh báo không được đề cập rõ ràng trong bài đăng này được bao gồm như một phần của một cảnh báo khác mà tôi đề cập. Nếu có ai nhận thấy bất kỳ cảnh báo nào bị loại trừ hoàn toàn khỏi bài đăng này, hãy cho tôi biết.

chỉnh sửa: Có vẻ như tôi đã bỏ lỡ một số (mà bây giờ tôi đã thêm vào). Trên thực tế, có một trang thứ hai tại http://gcc.gnu.org được ẩn khá kỹ. Tùy chọn cảnh báo chungtùy chọn C ++ (cuộn xuống dưới cùng để biết cảnh báo)


Gần đây, tôi đã gửi một yêu cầu nâng cao dựa trên nghiên cứu của mình cho câu trả lời này: gcc.gnu.org/bugzilla/show_bug.cgi?id=53313 . Nó sẽ đơn giản hóa đáng kể tình huống cảnh báo bằng cách tạo các mức cảnh báo. Trong đề nghị của tôi, bộ đề nghị của tôi về cảnh báo là khoảng -W4, với một đề xuất thêm để tạo -Winf, trong đó sẽ có nghĩa là -Weverything-and-I-thực sự-mean-it-này-thời gian
David Stone

Yêu cầu nâng cao sẽ khiến một phần của -Wpadded được thêm vào danh sách được đề xuất: gcc.gnu.org/bugzilla/show_bug.cgi?id=53514
David Stone,

Yêu cầu nâng cao sẽ khiến các phần của -Weffc ++ được thêm vào danh sách được đề xuất: gcc.gnu.org/bugzilla/show_bug.cgi?id=16166
David Stone,

1
@Predelnik: Nó phức tạp hơn thế. -Wswitch-enumcảnh báo nếu bạn không xử lý rõ ràng mọi giá trị liệt kê trong một công tắc và defaultkhông được tính là rõ ràng. Mặt khác, -Wswitch-defaultcảnh báo cho bạn nếu công tắc của bạn không có defaultvỏ, ngay cả khi bạn đã bao gồm tất cả các giá trị có thể một cách rõ ràng.
David Stone

2
BTW - sử dụng -isystemthay vì -Itrên "mã thư viện cũ" của bạn để ngăn chặn tất cả những dương tính giả
Galois

39

Ồ, tất cả các tìm kiếm ban đầu của tôi đều cho thấy 99% bài đăng về cách ngăn chặn cảnh báo (đủ đáng sợ), nhưng tôi vừa xem qua nhận xét này , có một bộ cờ đáng yêu này (một số ít liên quan hơn):

Kiểm tra chéo với:

http://gcc.gnu.org/onlineocs/gcc/Warning-Options.html

-g -O -Wall -Weffc++ -pedantic  \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security  \
-Wformat-y2k \
-Wimplicit  -Wimport  -Winit-self  -Winline \
-Winvalid-pch   \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute   \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked  -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings

Vì vậy, tôi nghĩ đó là một điểm khởi đầu tốt. Không nhận ra đây là một bản dupe, nhưng ít nhất nó đã được chôn sâu. :-)


1
Có lẽ, nhưng điều đó dường như thay đổi giữa các phiên bản, và có thể là tùy theo ý thích của các đốm mặt trời và RMS, vì vậy, quá rõ ràng có thể sẽ không gây hại. Đó là một điểm khởi đầu tốt, dù sao.
Sdaz MacSkibbons

3
Từ một bản tóm tắt nhanh c-opts.c / opts.c của 4.5.2 cho 'case OPT_W', bạn đang thiếu: nghiêm ngặt tràn, undef, nghiêm ngặt nul sentinel, chuẩn hóa, đa năng, khai báo hàm ẩn, không dùng nữa, nhãn endif, nhận xét s , macro nội trang được xác định lại, lớn hơn, lớn hơn eq, abi. Thật là điên rồ khi không có tùy chọn dòng lệnh để liệt kê chúng.
Tony Delroy

3
Tôi nghĩ nó điên rồ hơn khi -Wallkhông làm những gì người ta mong đợi. Nhưng cảm ơn bạn, một số trong số đó trông rất hữu ích!
Sdaz MacSkibbons

1
Việc tắt cảnh báo có vị trí của nó. Suy cho cùng, chúng là những “lời cảnh báo”. Một tình huống khác là khi bạn bật một cờ cho phép nhiều cảnh báo, nhưng bạn muốn chọn lọc về nó.
Tamás Szelei

1
Làm thế nào bạn có thể sử dụng -Waggregate-return? Điều này sẽ cho tôi một cảnh báo cho tất cả các sử dụngbegin/end()
Flamefire

13

Một số trong số đó đã được bao gồm trong -Wallhoặc -Wextra.

Một thiết lập cơ sở tốt cho C là:

-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror

và cho C ++

-ansi -pedantic -Wall -Wextra -Weffc++

(bỏ qua -WerrorC ++ vì -Weffc++có một số khó chịu)


10
-Werror có thể bị vô hiệu đối với các loại cụ thể của cảnh báo, ví dụ: -Werror -Weffc ++ -Wno-lỗi = effc ++
Robert Hensing

2
ansi : Trong chế độ C, điều này tương đương với -std=c89. Trong chế độ C ++, nó tương đương với -std=c++98. tức là nếu bạn đang xác định một số khác std, dont sử dụngansi
Sean Breckenridge

2

Thử

export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' |
sort | uniq` -pedantic -fdiagnostics-show-option -Werror"

Đó là một khởi đầu nhanh chóng và bẩn thỉu mà chắc chắn sẽ cần một số điều chỉnh; đối với một điều, ngay cả khi bạn gọi trình biên dịch bằng tên thích hợp cho ngôn ngữ của bạn (ví dụ: g++đối với C ++), bạn sẽ nhận được cảnh báo không áp dụng cho ngôn ngữ đó (và trình biên dịch sẽ bó tay và từ chối tiếp tục cho đến khi bạn loại bỏ cảnh báo).

Một điều nữa là tôi đã thêm vào -Werror, bởi vì nếu bạn không sửa các cảnh báo, tại sao bạn lại quan tâm đến việc bật chúng? Bạn cũng có thể đưa các cảnh báo ra khỏi danh sách. (Ví dụ: tôi hầu như không bao giờ sử dụng -Waggregate-returnvới C ++.)

Một số cảnh báo sẽ không làm được gì nếu không có các tùy chọn liên quan đến hiệu suất khác ( -Wstack-protector). -fdiagnostics-show-optionvà sổ tay GCC là bạn của bạn.

Nhân tiện, một số cảnh báo loại trừ lẫn nhau; đặc biệt bằng cách sử dụng -Wtraditional-Wold-style-definitioncùng với -Werror, sẽ không biên dịch.


0

Trong CmakeLists.txt của Clion của tôi

cmake_minimum_required(VERSION 3.13)
project(cpp17)

set(CMAKE_CXX_STANDARD 17)

set(GCC_COVERAGE_COMPILE_FLAGS "-std=c++17 -Wall -Weffc++ -Wno-error=effc++ -pedantic \
 -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-newline-eof  \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security  \
-Wformat-y2k \
-Wimplicit  -Wimport  -Winit-self  -Winline -Winvalid-pch   \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute   \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked  -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings")


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )

add_executable(cpp17 main.cpp)
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.