Có lý do gì để sử dụng C thay vì C ++ để phát triển nhúng không?


81

Câu hỏi

Tôi có hai trình biên dịch trên phần cứng C ++ và C89 của mình

Tôi đang nghĩ về việc sử dụng C ++ với các lớp nhưng không có tính đa hình (để tránh các vtables). Những lý do chính tôi muốn sử dụng C ++ là:

  • Tôi thích sử dụng các hàm "nội tuyến" thay vì các định nghĩa macro.
  • Tôi muốn sử dụng không gian tên vì tôi đặt tiền tố làm lộn xộn mã.
  • Tôi thấy C ++ là một loại bit an toàn hơn chủ yếu vì các mẫu và truyền dài dòng.
  • Tôi thực sự thích các hàm và hàm tạo bị quá tải (được sử dụng để đúc tự động).

Bạn có thấy lý do gì để gắn bó với C89 khi phát triển cho phần cứng rất hạn chế (RAM 4kb) không?

Phần kết luận

Cảm ơn bạn đã trả lời, chúng thực sự hữu ích!

Tôi đã nghĩ chủ đề này thông suốt và tôi sẽ gắn bó với C chủ yếu vì:

  1. Dự đoán mã thực tế trong C dễ dàng hơn và điều này thực sự quan trọng nếu bạn chỉ có 4kb ram.
  2. Nhóm của tôi chủ yếu bao gồm các nhà phát triển C, vì vậy các tính năng C ++ nâng cao sẽ không được sử dụng thường xuyên.
  3. Tôi đã tìm thấy một cách để nội tuyến các hàm trong trình biên dịch C (C89) của mình.

Thật khó để chấp nhận một câu trả lời vì bạn đã cung cấp rất nhiều câu trả lời hay. Rất tiếc, tôi không thể tạo wiki và chấp nhận nó, vì vậy tôi sẽ chọn một câu trả lời khiến tôi suy nghĩ nhiều nhất.


11
Một điều: hãy luôn hoàn toàn rõ ràng bạn đang viết bằng ngôn ngữ nào. Đừng cố gắng viết một chương trình bằng "C / C ++". Viết bằng C hoặc viết bằng C ++ khi biết bạn sẽ sử dụng tính năng ngôn ngữ nào và không sử dụng tính năng nào.
David Thornley


Xác định "phát triển nhúng"
Marco van de Voort

@DavidThornley, bạn có thể đúng với các trường hợp nhúng, nhưng tôi đã rất ngạc nhiên về cách mã C & C ++ hỗn hợp độc đáo chơi với nhau khi tôi đang tìm cách mở rộng các ứng dụng nguồn mở phổ biến trong ngành như Kamailio với STL. Tôi chính thức khuyến khích việc sử dụng mã STL và C này, vì nó cung cấp chức năng to lớn và dễ bảo trì về sau, trong khi hầu như không tạo ra vấn đề gì (việc thiếu cấu trúc nhúng trong C ++ là một tội ác khủng khiếp đối với C ++ và cần được khắc phục càng sớm càng tốt ).
dùng2548100

Thực phẩm cho sự suy nghĩ, đây là một bài viết tuyệt vời trong đó nhà thiết kế và nhà văn của ZeroMQ thảo luận về lý do tại sao anh ấy hối tiếc khi viết cơ sở mã bằng C ++ thay vì C. Không phải những gì tôi mong đợi và vì những lý do không tìm thấy ở nơi khác trên trang này. 250bpm.com/blog:4
dùng2548100

Câu trả lời:


47

Hai lý do để sử dụng C thay vì C ++:

  1. Đối với nhiều bộ xử lý nhúng, hoặc không có trình biên dịch C ++ hoặc bạn phải trả thêm tiền cho nó.
  2. Kinh nghiệm của tôi là một tỷ lệ rất lớn các kỹ sư phần mềm nhúng có ít hoặc không có kinh nghiệm về C ++ - vì (1), hoặc vì nó có xu hướng không được dạy về các bằng kỹ sư điện tử - và vì vậy tốt hơn là bạn nên gắn bó với những gì họ biết.

Ngoài ra, câu hỏi ban đầu và một số ý kiến, đề cập đến RAM 4 Kb . Đối với một bộ xử lý nhúng điển hình, dung lượng RAM (hầu hết) không liên quan đến kích thước mã, vì mã được lưu trữ và chạy từ flash.

Chắc chắn, số lượng không gian lưu trữ mã là điều cần lưu ý, nhưng khi các bộ vi xử lý mới, dung lượng hơn, xuất hiện trên thị trường, nó ít là vấn đề hơn so với trước đây đối với tất cả trừ các dự án nhạy cảm về chi phí.

Về việc sử dụng một tập hợp con của C ++ để sử dụng với các hệ thống nhúng: hiện có một tiêu chuẩn MISRA C ++ , có thể đáng để xem xét.

CHỈNH SỬA: Xem thêm câu hỏi này , dẫn đến cuộc tranh luận về C và C ++ cho các hệ thống nhúng.


2
Xem câu trả lời dài hơn của tôi bên dưới: C ++ có xu hướng làm cho việc đưa dữ liệu liên tục vào FLASH rất khó khăn.
jakobengblom2

3
Lý do chính đáng để sử dụng C thay vì C ++ là ABI tiêu chuẩn của C. Chỉ cho sự hoàn chỉnh.
Chris Lutz

66

Đối với một rất mục tiêu hạn chế tài nguyên như 4KB RAM, tôi muốn kiểm tra các vùng biển với một số mẫu trước khi cam kết rất nhiều nỗ lực đó không thể dễ dàng được chuyển trở lại thành một tinh khiết thực hiện ANSI C.

Nhóm làm việc Embedded C ++ đã đề xuất một tập hợp con tiêu chuẩn của ngôn ngữ và một tập hợp con tiêu chuẩn của thư viện tiêu chuẩn đi kèm với nó. Thật không may, tôi đã mất dấu nỗ lực đó khi Tạp chí Người dùng C qua đời. Có vẻ như có một bài báo trên Wikipedia , và ủy ban đó vẫn tồn tại.

Trong môi trường nhúng, bạn thực sự phải cẩn thận về việc cấp phát bộ nhớ. Để thực thi sự quan tâm đó, bạn có thể cần phải xác định toàn cầu operator new()và bạn bè của nó với một thứ gì đó thậm chí không thể liên kết để bạn biết rằng nó không được sử dụng. newMặt khác, vị trí có thể là bạn của bạn, khi được sử dụng một cách thận trọng cùng với một sơ đồ phân bổ ổn định, an toàn theo luồng và đảm bảo độ trễ.

Các hàm nội tuyến sẽ không gây ra nhiều vấn đề, trừ khi chúng đủ lớn để ngay từ đầu chúng phải là các hàm thực sự. Tất nhiên các macro mà họ thay thế cũng có vấn đề tương tự.

Các khuôn mẫu cũng vậy, có thể không gây ra sự cố trừ khi việc khởi tạo của chúng chạy amok. Đối với bất kỳ mẫu nào bạn sử dụng, hãy kiểm tra mã đã tạo của bạn (bản đồ liên kết có thể có đủ manh mối) để đảm bảo rằng chỉ các bản thuyết minh bạn dự định sử dụng mới xảy ra.

Một vấn đề khác có thể phát sinh là khả năng tương thích với trình gỡ lỗi của bạn. Không có gì lạ khi một trình gỡ lỗi phần cứng có thể sử dụng được lại hỗ trợ rất hạn chế cho việc tương tác với mã nguồn gốc. Nếu bạn thực sự phải gỡ lỗi trong hợp ngữ, thì tên gọi thú vị của C ++ có thể gây thêm nhầm lẫn cho nhiệm vụ.

RTTI, phôi động, đa kế thừa, đa hình nặng và ngoại lệ đều đi kèm với một số chi phí thời gian chạy để sử dụng chúng. Một vài trong số những tính năng đó có mức chi phí trên toàn bộ chương trình nếu chúng được sử dụng, những tính năng khác chỉ làm tăng trọng lượng của các lớp cần chúng. Biết sự khác biệt và lựa chọn các tính năng nâng cao một cách khôn ngoan với đầy đủ kiến ​​thức về ít nhất là phân tích chi phí / lợi ích sơ lược.

Trong một môi trường nhúng nhỏ, bạn sẽ liên kết trực tiếp với nhân thời gian thực hoặc chạy trực tiếp trên phần cứng. Dù bằng cách nào, bạn sẽ cần đảm bảo rằng mã khởi động thời gian chạy của bạn xử lý các công việc khởi động cụ thể của C ++ một cách chính xác. Điều này có thể đơn giản như đảm bảo sử dụng các tùy chọn trình liên kết phù hợp, nhưng vì thông thường có quyền kiểm soát trực tiếp nguồn đối với điểm nhập nguồn bật lại, bạn có thể cần phải kiểm tra điều đó để đảm bảo rằng nó thực hiện mọi thứ. Ví dụ: trên nền tảng ColdFire mà tôi đã làm việc, các công cụ dành cho nhà phát triển được vận chuyển cùng với mô-đun CRT0.S có trình khởi tạo C ++ nhưng không có nhận xét. Nếu tôi sử dụng nó ngay từ hộp, tôi sẽ bị bối rối bởi các đối tượng toàn cục mà các hàm tạo của chúng chưa bao giờ chạy.

Ngoài ra, trong môi trường nhúng, thông thường cần phải khởi tạo các thiết bị phần cứng trước khi chúng có thể được sử dụng, và nếu không có hệ điều hành và không có bộ tải khởi động, thì mã của bạn sẽ thực hiện điều đó. Bạn sẽ cần nhớ rằng các hàm tạo cho các đối tượng toàn cục được chạy trước khi main() được gọi, vì vậy bạn sẽ cần sửa đổi CRT0.S cục bộ của mình (hoặc tương đương) để thực hiện khởi tạo phần cứng đó trước khi chính các hàm tạo toàn cục được gọi. Rõ ràng, đầu của main()là quá muộn.


1
Cái này cần nhiều lượt ủng hộ hơn tôi có thể cho! Câu trả lời chính xác.
Harper Shelby

+1, câu trả lời tuyệt vời. Nhưng tôi nghĩ rằng cách khởi tạo mẫu duy nhất mà bạn thực sự cần phải lo lắng là loại đệ quy (tương đối hiếm) - đối với loại không đệ quy "thông thường", việc khởi tạo cũng giống như mã bạn đã nhập theo cách thủ công.
j_random_hacker

2
@j_random_hacker, đúng. Nhưng thói quen của các khuôn mẫu có thể dẫn đến những bất ngờ không thường xuyên khi một bản khởi tạo thứ hai (hoặc thứ ba) xuất hiện trong đó sự ép buộc kiểu thích hợp tại thời điểm sử dụng có thể đã ngăn cản nó. Nó chỉ là một cái gì đó để xem cho.
RBerteig

@RBerteig: Điểm tốt, các mẫu cho phép ít khả năng cưỡng chế kiểu hơn => có thể tạo ra nhiều bản thuyết minh khác biệt hơn so với mã không phải mẫu.
j_random_hacker

26

Không. Bất kỳ tính năng ngôn ngữ C ++ nào có thể gây ra sự cố (đa hình thời gian chạy, RTTI, v.v.) đều có thể tránh được khi thực hiện phát triển nhúng. Có một cộng đồng các nhà phát triển C ++ nhúng (tôi nhớ đã đọc các cột của các nhà phát triển nhúng sử dụng C ++ trong Tạp chí Người dùng C / C ++ cũ), và tôi không thể tưởng tượng được họ sẽ rất mạnh miệng nếu lựa chọn tệ đến vậy.


20

Các Báo cáo kỹ thuật về ++ Performance C là một hướng dẫn tuyệt vời cho các loại điều này. Lưu ý rằng nó có một phần về các mối quan tâm về lập trình nhúng!

Ngoài ra, ++ khi đề cập đến Embedded C ++ trong câu trả lời. Tiêu chuẩn không phải là 100% theo sở thích của tôi, nhưng đó là một chút tham khảo tốt khi quyết định bạn có thể bỏ phần nào của C ++.

Trong khi lập trình cho các nền tảng nhỏ, chúng tôi vô hiệu hóa các ngoại lệ và RTTI, tránh kế thừa ảo và chú ý đến số lượng các chức năng ảo mà chúng tôi có.

Tuy nhiên, bạn của bạn là bản đồ của trình liên kết: hãy kiểm tra nó thường xuyên, và bạn sẽ nhanh chóng phát hiện ra các nguồn mã và bộ nhớ tĩnh phình to.

Sau đó, các cân nhắc sử dụng bộ nhớ động tiêu chuẩn được áp dụng: trong một môi trường bị hạn chế như môi trường bạn đề cập, bạn có thể không muốn sử dụng phân bổ động. Đôi khi bạn có thể sử dụng các vùng bộ nhớ cho các phân bổ động nhỏ hoặc phân bổ "dựa trên khung" trong đó bạn phân bổ trước một khối và loại bỏ toàn bộ sau.


16

Tôi khuyên bạn nên sử dụng trình biên dịch C ++, nhưng hạn chế sử dụng các tính năng cụ thể của C ++. Bạn có thể lập trình như C trong C ++ (thời gian chạy C được bao gồm khi thực hiện C ++, mặc dù trong hầu hết các ứng dụng nhúng, bạn vẫn không sử dụng thư viện chuẩn).

Bạn có thể tiếp tục và sử dụng các lớp C ++, v.v., chỉ

  • Hạn chế sử dụng các chức năng ảo (như bạn đã nói)
  • Hạn chế sử dụng các mẫu
  • Đối với một nền tảng nhúng, bạn sẽ muốn ghi đè toán tử mới và / hoặc sử dụng vị trí mới để cấp phát bộ nhớ.

8
Tất nhiên, nếu bạn đã viết C về cơ bản, bạn cũng có thể biến nó thành chính thức.
Chuck

6
Tại sao bạn hạn chế sử dụng Mẫu? Tôi đã nghĩ rằng các hàm mẫu có thể thực sự hữu ích trong các hệ thống nhúng, chẳng hạn như để giải nén các vòng lặp.
Piotr Czapla

1
Bạn vẫn có thể sử dụng các mẫu, nhưng tôi sẽ rất cẩn thận với chúng, vì chúng có thể nhanh chóng tăng kích thước của tệp nhị phân đầu ra. Tất nhiên, nếu mã của bạn chạy trực tiếp từ ROM hoặc tương tự và bạn có dung lượng ROM để dự phòng, thì chắc chắn rồi, nhưng ngoài điều đó, bạn cần phải cẩn thận với những gì bạn làm với các mẫu (mỗi phiên bản mẫu về cơ bản là tất cả các mã mẫu được sao chép lại trong tệp thực thi cuối cùng trong trường hợp xấu nhất).
arke

14

Là một kỹ sư phần mềm / hệ thống nhúng, tôi có thể cho các bạn biết một số lý do tại sao C vẫn là lựa chọn số 1 so với C ++ và vâng, tôi thông thạo cả hai.

1) Một số mục tiêu mà chúng tôi phát triển trên có 64kB RAM cho cả mã và dữ liệu, vì vậy bạn phải đảm bảo số lượng từng byte và vâng, tôi đã xử lý tối ưu hóa mã để tiết kiệm 4 byte, tiêu tốn của tôi 2 giờ và đó là Năm 2008.

2) Mọi hàm thư viện C đều được xem xét trước khi chúng tôi đưa chúng vào mã cuối cùng, vì giới hạn kích thước, vì vậy chúng tôi không muốn mọi người sử dụng chia (không có bộ chia phần cứng, vì vậy cần có một thư viện lớn), malloc (vì chúng tôi không có heap , tất cả bộ nhớ được cấp phát từ bộ đệm dữ liệu trong 512 byte chunk và phải được xem xét mã), hoặc thực hành hướng đối tượng khác có hình phạt lớn. Hãy nhớ rằng, mọi hàm thư viện mà bạn sử dụng đều được đếm.

3) Bạn đã từng nghe đến thuật ngữ lớp phủ? bạn có ít không gian mã đến mức đôi khi bạn phải hoán đổi mọi thứ bằng một bộ mã khác. Nếu bạn gọi một hàm thư viện thì hàm thư viện phải thường trú. Nếu bạn chỉ sử dụng nó trong một chức năng lớp phủ, bạn đang lãng phí rất nhiều dung lượng khi dựa vào quá nhiều phương thức hướng đối tượng. Vì vậy, đừng giả sử bất kỳ hàm thư viện C nào, hãy để một mình C ++ được chấp nhận.

4) Truyền và thậm chí đóng gói (trong đó cấu trúc dữ liệu không được căn chỉnh vượt qua ranh giới từ) là cần thiết do thiết kế phần cứng hạn chế (tức là công cụ ECC được kết nối theo một cách nhất định) hoặc để đối phó với lỗi phần cứng. Bạn không thể giả định quá nhiều, vậy tại sao đối tượng lại định hướng nó quá nhiều?

5) Trường hợp xấu nhất: loại bỏ một số phương pháp hướng đối tượng sẽ buộc phát triển phải suy nghĩ trước khi chúng sử dụng các tài nguyên có thể bùng nổ (tức là phân bổ 512byte trên một ngăn xếp thay vì từ bộ đệm dữ liệu) và ngăn ngừa một số trường hợp xấu nhất tiềm ẩn xảy ra không được kiểm tra hoặc loại bỏ toàn bộ đường dẫn mã cùng nhau.

6) Chúng tôi sử dụng rất nhiều trừu tượng để giữ phần cứng khỏi phần mềm và làm cho mã di động nhất có thể và thân thiện với mô phỏng. Quyền truy cập phần cứng phải được bao bọc trong một hàm macro hoặc hàm nội tuyến được biên dịch có điều kiện giữa các nền tảng khác nhau, kiểu dữ liệu phải được truyền dưới dạng kích thước byte thay vì mục tiêu cụ thể, không được phép sử dụng con trỏ trực tiếp (vì một số nền tảng cho rằng I / O được ánh xạ bộ nhớ là giống như bộ nhớ dữ liệu), v.v.

Tôi có thể nghĩ ra nhiều thứ hơn, nhưng bạn hiểu rồi đấy. Những người làm phần mềm cơ sở của chúng tôi có đào tạo về hướng đối tượng, nhưng nhiệm vụ của hệ thống nhúng có thể hướng đến phần cứng và mức thấp, đến mức nó không phải là mức cao hoặc không thể trừu tượng hóa về bản chất.

BTW, mọi công việc phần sụn tôi đã làm đều sử dụng điều khiển nguồn, tôi không biết bạn lấy ý tưởng đó từ đâu.

- một anh chàng phần sụn nào đó từ SanDisk.


trở lại trong đầu 90, lớp phủ là kỹ thuật rất phổ biến (ít nhất là trong thế giới DOS)
psihodelia

Điểm tốt Shing. C ++ có cảm giác giống như một đô vật Sumo trong buồng điện thoại trên các dự án mà chức năng bị hạn chế và tài nguyên thậm chí còn hạn chế hơn.

4
Tôi tin rằng câu trả lời này rất chủ quan và không cung cấp lý do cụ thể.
Venemo

1
C ++ không nhất thiết có nghĩa là "hướng đối tượng".
Martin Bonner hỗ trợ Monica

1
Đơn giản là không đúng vì bản chất nhiệm vụ của hệ thống nhúng không trừu tượng. Bạn đã tự nói điều đó ở điểm 6): "chúng tôi sử dụng rất nhiều trừu tượng để giữ hw khỏi sw và làm cho mã di động nhất có thể" :-) BTW: "trừu tượng" không nhất thiết ngụ ý "đa hình".
Daniele Pallastrelli

9

Sở thích cá nhân của tôi là C vì:

  • Tôi biết mọi dòng mã đang làm gì (và chi phí)
  • Tôi không hiểu rõ về C ++ để biết mọi dòng mã đang làm gì (và chi phí)

Tại sao mọi người nói điều này? Bạn không biết mọi dòng C đang làm gì trừ khi bạn kiểm tra đầu ra asm. Tương tự với C ++.

Ví dụ, câu lệnh vô tội này tạo ra asm gì:

a[i] = b[j] * c[k];

Nó trông khá ngây thơ, nhưng một trình biên dịch dựa trên gcc tạo ra asm này cho một vi 8 bit

CLRF 0x1f, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1f, F, ACCESS
MOVWF 0x1e, ACCESS
MOVLW 0xf9
MOVF 0xfdb, W, ACCESS
ADDWF 0x1e, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfa
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1f, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x1c
NOP
MOVFF 0xfef, 0x1d
NOP
MOVLW 0x1
CLRF 0x1b, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1b, F, ACCESS
MOVWF 0x1a, ACCESS
MOVLW 0xfb
MOVF 0xfdb, W, ACCESS
ADDWF 0x1a, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfc
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1b, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x18
NOP
MOVFF 0xfef, 0x19
NOP
MOVFF 0x18, 0x8
NOP
MOVFF 0x19, 0x9
NOP
MOVFF 0x1c, 0xd
NOP
MOVFF 0x1d, 0xe
NOP
CALL 0x2142, 0
NOP
MOVFF 0x6, 0x16
NOP
MOVFF 0x7, 0x17
NOP
CLRF 0x15, ACCESS
RLCF 0xfdf, W, ACCESS
ANDLW 0xfe
RLCF 0x15, F, ACCESS
MOVWF 0x14, ACCESS
MOVLW 0xfd
MOVF 0xfdb, W, ACCESS
ADDWF 0x14, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfe
MOVF 0xfdb, W, ACCESS
ADDWFC 0x15, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0x16, 0xfee
NOP
MOVFF 0x17, 0xfed
NOP

Số lượng hướng dẫn được tạo ra phụ thuộc vào:

  • Kích thước của a, b và c.
  • cho dù những con trỏ đó được lưu trữ trên ngăn xếp hay toàn cục
  • cho dù tôi, j và k nằm trên ngăn xếp hay toàn cục

Điều này đặc biệt đúng trong thế giới nhúng nhỏ bé, nơi các bộ xử lý không được thiết lập để xử lý C. Vì vậy, câu trả lời của tôi sẽ là C và C ++ tệ như nhau, trừ khi bạn luôn kiểm tra đầu ra asm, trong trường hợp đó chúng tốt như nhau.

Hugo


2
Cũng lưu ý rằng có một lệnh gọi ở giữa tất cả những gì thực sự gọi hàm nhân. Tất cả mã đó thậm chí không phải là lệnh nhân!
Rocketmagnet

Ai đó quen thuộc với vi mô thường sẽ biết một cách đơn giản để xử lý từng phần của mã C một cách riêng biệt và một trình biên dịch tốt sẽ không tạo ra mã tồi tệ hơn thế. Cách duy nhất để biểu thức trên có thể được xử lý một cách hiệu quả là nếu người ta đưa ra các giả định có thể không phù hợp với trình biên dịch C.
supercat

8

Tôi đã nghe nói rằng một số người thích C cho công việc nhúng do thực tế là đơn giản hơn và do đó dễ dàng dự đoán mã thực tế sẽ được tạo.

Cá nhân tôi nghĩ rằng viết C-style C ++ (sử dụng các mẫu để đảm bảo an toàn cho kiểu chữ) sẽ mang lại cho bạn rất nhiều lợi thế và tôi không thể thấy lý do thực sự nào để không làm như vậy.


+1, tính minh bạch luôn quan trọng và có lẽ còn hơn thế nữa đối với một môi trường hạn chế với các công cụ gỡ lỗi bị hạn chế (có thể là).
j_random_hacker

7

Tôi thấy không có lý do gì để sử dụng C thay vì C ++. Bất cứ điều gì bạn có thể làm trong C, bạn cũng có thể làm điều đó trong C ++. Nếu bạn muốn tránh các chi phí chung của VMT, đừng sử dụng các phương pháp ảo và đa hình.

Tuy nhiên, C ++ có thể cung cấp một số thành ngữ rất hữu ích mà không tốn phí. Một trong những mục yêu thích của tôi là RAII. Các lớp không cần thiết đắt tiền về bộ nhớ hoặc hiệu suất ...


6

Tôi đã viết một số mã cho biểu mẫu nhúng ARM7 trên IAR Workbench. Tôi thực sự khuyên bạn nên dựa vào các mẫu để thực hiện tối ưu hóa thời gian biên dịch và dự đoán đường dẫn. Tránh truyền động như bệnh dịch. Sử dụng các đặc điểm / chính sách có lợi cho bạn, như được quy định trong cuốn sách của Andrei Alexandrescu, Thiết kế C ++ hiện đại .

Tôi biết, có thể khó học, nhưng tôi cũng chắc chắn rằng sản phẩm của bạn sẽ được hưởng lợi từ cách tiếp cận này.


5

Một lý do chính đáng và đôi khi là lý do duy nhất là vẫn chưa có trình biên dịch C ++ cho hệ thống nhúng cụ thể. Đây là trường hợp ví dụ đối với bộ vi điều khiển Microchip PIC . Chúng rất dễ viết và chúng có một trình biên dịch C miễn phí (thực ra là một biến thể nhỏ của C) nhưng không có trình biên dịch C ++ nào trong tầm mắt.


1
Comeau Computing ( goaucomputing.com ) bán một trình biên dịch C ++ được biên dịch sang C.
Thomas L Holaday

3
Ghê quá. Trang web đó làm cho muốn nôn.
shoosh

@shoosh: Vâng, thiết kế trang web thật tệ. Tuy nhiên, bản thân trình biên dịch được coi là người dẫn đầu trong lĩnh vực này, ít nhất là về mặt tuân thủ tiêu chuẩn (tôi không có thông tin về hiệu suất).
j_random_hacker

Trang web đó khiến tôi cảm thấy như đang bị mắc kẹt bên trong một món salad trái cây đang sống, đang thở và RẤT tức giận.
Tim Đăng

5

Đối với một hệ thống bị giới hạn ở 4K ram, tôi sẽ sử dụng C, không phải C ++, để bạn có thể chắc chắn xem mọi thứ đang diễn ra. Vấn đề với C ++ là rất dễ dàng sử dụng nhiều tài nguyên hơn (cả CPU và bộ nhớ) so với việc nhìn lướt qua mã. (Ồ, tôi sẽ tạo một BlerfObject khác để làm điều đó ... rất tiếc! Hết bộ nhớ!)

Bạn có thể làm điều đó trong C ++, như đã đề cập (không có RTTI, không có vtables, v.v.), nhưng bạn sẽ dành nhiều thời gian để đảm bảo rằng việc sử dụng C ++ của bạn không bị ảnh hưởng bởi bạn làm tương tự trong C .


2
Câu cuối cùng của bạn là đúng nhưng không liên quan vì C ++ cung cấp các lợi thế khác so với C mà (có thể) đưa ra số dư. Piotr đã đề cập đến một số lợi thế (chi phí bằng không) này.
Konrad Rudolph

5

Trí óc con người đối phó với sự phức tạp bằng cách đánh giá càng nhiều càng tốt, sau đó quyết định điều gì quan trọng cần tập trung vào, loại bỏ hoặc giảm giá phần còn lại. Đây là toàn bộ nền tảng đằng sau việc xây dựng thương hiệu trong Tiếp thị và phần lớn là các biểu tượng.

Để chống lại xu hướng này, tôi thích C hơn C ++, vì nó buộc bạn phải suy nghĩ về mã của mình và cách nó tương tác với phần cứng chặt chẽ hơn - gần như không ngừng.

Từ kinh nghiệm lâu năm, tôi tin rằng C buộc bạn phải đưa ra các giải pháp tốt hơn cho các vấn đề, một phần, bằng cách thoát ra khỏi con đường của bạn và không buộc bạn phải lãng phí nhiều thời gian để thỏa mãn một hạn chế mà một số người viết trình biên dịch nghĩ là một ý kiến ​​hay hoặc tìm ra những gì đang diễn ra "dưới vỏ bọc".

Trong bối cảnh đó, các ngôn ngữ cấp thấp như C khiến bạn dành nhiều thời gian tập trung vào phần cứng và xây dựng các gói thuật toán / cấu trúc dữ liệu tốt, trong khi các ngôn ngữ cấp cao khiến bạn phải mất nhiều thời gian để tự hỏi điều gì đang xảy ra trong đó và tại sao bạn không thể làm điều gì đó hoàn toàn hợp lý trong bối cảnh và môi trường cụ thể của bạn. Đánh bại trình biên dịch của bạn để phục vụ (gõ mạnh là hành vi vi phạm tồi tệ nhất) KHÔNG phải là cách sử dụng thời gian hiệu quả.

Tôi có lẽ phù hợp với khuôn lập trình viên - Tôi thích kiểm soát. Theo quan điểm của tôi, đó không phải là một khuyết điểm về nhân cách của một lập trình viên. Kiểm soát là những gì chúng ta được trả tiền để làm. Đặc biệt hơn, điều khiển FLAWLESSLY. C cung cấp cho bạn nhiều quyền kiểm soát hơn C ++.


Martin Sistrik, tác giả của ZeroMQ đã đưa ra quan điểm gần như tương tự trong cuộc thảo luận của mình về lý do tại sao anh ấy muốn bây giờ anh ấy viết ZeroMQ bằng C, thay vì C ++. Check it out 250bpm.com/blog:8
user2548100

3

Cá nhân với 4kb bộ nhớ, tôi muốn nói rằng bạn sẽ không nhận được nhiều hơn nữa từ C ++, vì vậy chỉ cần chọn một trong những có vẻ như kết hợp trình biên dịch / thời gian chạy tốt nhất cho công việc, vì ngôn ngữ có lẽ sẽ không quan trọng nhiều.

Lưu ý rằng dù sao nó cũng không phải là tất cả về ngôn ngữ, vì thư viện cũng quan trọng. Thường thì các lib C có kích thước tối thiểu nhỏ hơn một chút, nhưng tôi có thể tưởng tượng rằng một lib C ++ nhắm mục tiêu phát triển nhúng bị cắt giảm, vì vậy hãy đảm bảo kiểm tra.


2

C thắng về tính di động - vì nó ít mơ hồ hơn trong đặc tả ngôn ngữ; do đó cung cấp tính di động và tính linh hoạt tốt hơn nhiều trên các trình biên dịch khác nhau, v.v. (ít đau đầu hơn).

Nếu bạn không tận dụng các tính năng của C ++ để đáp ứng nhu cầu thì hãy sử dụng C.


Liệu ngôn ngữ có rõ ràng hay không phụ thuộc vào việc người ta có coi nó là chỉ định những thứ từng được coi là thông thường hay không, nhưng ngày nay thì không [ví dụ: một trình biên dịch cho phần cứng bổ sung hai của 32 bit im lặng nên xử lý một cái gì đó giống unsigned mul(unsigned short x, unsigned short y) { return x*y;}như không có tác dụng phụ ngay cả khi sản phẩm vượt quá 2147483647 hoặc sản phẩm void get_float_bits(float *fp, uint32_t n) { *(uint32_t)fp = n; }có thể làm thay đổi giá trị của a float].
supercat

2

Bạn có thấy lý do gì để gắn bó với C89 khi phát triển cho phần cứng rất hạn chế (RAM 4kb) không?

Cá nhân, khi nói đến các ứng dụng nhúng (Khi tôi nói nhúng, tôi không có nghĩa là winCE, iPhone, v.v. ngày nay các thiết bị nhúng cồng kềnh). Ý tôi là thiết bị hạn chế tài nguyên. Tôi thích C hơn, mặc dù tôi cũng đã làm việc với C ++ khá nhiều.

Ví dụ: thiết bị bạn đang nói đến có RAM 4kb , vì lý do đó tôi sẽ không xem xét C ++. Chắc chắn, bạn có thể thiết kế một cái gì đó nhỏ bằng cách sử dụng C ++ và giới hạn việc sử dụng nó trong ứng dụng của bạn như các bài viết khác đã đề xuất nhưng C ++ "có thể" có khả năng làm phức tạp / phình to ứng dụng của bạn.

Bạn sẽ liên kết tĩnh? Bạn có thể muốn so sánh tĩnh một ứng dụng giả sử dụng c ++ với c. Điều đó có thể khiến bạn cân nhắc C thay thế. Mặt khác, nếu bạn có thể xây dựng một ứng dụng C ++ trong phạm vi yêu cầu bộ nhớ của mình, hãy tiếp tục.

IMHO, Nói chung, trong các ứng dụng nhúng, tôi muốn biết mọi thứ đang diễn ra. Ai đang sử dụng bộ nhớ / tài nguyên hệ thống, bao nhiêu và tại sao? Khi nào họ giải phóng chúng?

Khi phát triển cho một mục tiêu với X lượng tài nguyên, cpu, bộ nhớ, v.v. Tôi cố gắng ở mức thấp hơn trong việc sử dụng các tài nguyên đó bởi vì bạn không bao giờ biết yêu cầu nào trong tương lai sẽ xảy ra do đó bạn phải thêm nhiều mã hơn vào dự án được cho là một ứng dụng nhỏ đơn giản nhưng cuối cùng lại trở nên lớn hơn rất nhiều.


1
Tôi chắc chắn sẽ so sánh hai trình biên dịch. (btw. Tôi không thể Liên kết động vì không có hệ điều hành)
Piotr Czapla

2

Sự lựa chọn của tôi thường được xác định bởi thư viện C mà chúng tôi quyết định sử dụng, được chọn dựa trên những gì thiết bị cần làm. Vì vậy, 9/10 lần .. nó kết thúc là uclibc hoặc newlib và C. Kernel chúng ta sử dụng cũng có ảnh hưởng lớn đến điều này, hoặc nếu chúng ta đang viết kernel của chính mình.

Nó cũng là một sự lựa chọn của mặt bằng chung. Hầu hết các lập trình viên C giỏi không gặp vấn đề gì khi sử dụng C ++ (mặc dù nhiều người phàn nàn rằng họ sử dụng nó) .. nhưng tôi không thấy điều ngược lại là đúng (theo kinh nghiệm của tôi).

Trong một dự án mà chúng tôi đang thực hiện (liên quan đến một nhân cơ bản), hầu hết mọi thứ đều được thực hiện bằng C, tuy nhiên, một ngăn xếp mạng nhỏ đã được thực hiện trong C ++, bởi vì việc triển khai mạng bằng C ++ dễ dàng hơn và ít vấn đề hơn.

Kết quả cuối cùng là, thiết bị sẽ hoạt động và vượt qua các bài kiểm tra chấp nhận hoặc không. Nếu bạn có thể triển khai foo trong xx stack và các ràng buộc heap yy bằng ngôn ngữ z, hãy tiếp tục, sử dụng bất cứ điều gì khiến bạn năng suất hơn.

Sở thích cá nhân của tôi là C vì:

  • Tôi biết mọi dòng mã đang làm gì (và chi phí)
  • Tôi không hiểu rõ về C ++ để biết mọi dòng mã đang làm gì (và chi phí)

Có, tôi cảm thấy thoải mái với C ++, nhưng tôi không biết nó cũng như tôi làm tiêu chuẩn C.

Bây giờ nếu bạn có thể nói ngược lại điều đó, tốt, hãy sử dụng những gì bạn biết :) Nếu nó hoạt động, vượt qua các bài kiểm tra, v.v. thì vấn đề là gì?


2
> # Tôi biết mọi dòng mã đang làm gì (và chi phí) Đã viết trình biên dịch, tôi sẽ không chắc về điều đó ... một trình biên dịch C tốt có thể làm những điều khá ngạc nhiên đối với mã của bạn vì nó có một cái nhìn tổng quan toàn cầu về nhiều thứ. Nó không biên dịch từng dòng một.
jakobengblom2

@ jakobengblom2: Đối với phát triển nhúng, có hiệu suất nhất quán thường quan trọng hơn là có hiệu suất tối đa. Nếu một người đang cố gắng xác định xem một đoạn mã có đáp ứng các yêu cầu về thời gian hay không, thì việc yêu cầu một trình biên dịch sử dụng các tính năng tối ưu hóa sẽ có thể sử dụng được trong phần sụn "thử nghiệm" mà không hoạt động trong phần sụn thực sẽ ít hữu ích hơn.
supercat

2

Bạn có bao nhiêu ROM / FLASH?

RAM 4kB vẫn có nghĩa là có hàng trăm kilobyte FLASH để lưu trữ mã thực và dữ liệu tĩnh. RAM trên kích thước này có xu hướng chỉ dành cho các biến và nếu bạn cẩn thận với những biến đó, bạn có thể đưa một chương trình khá lớn về các dòng mã vào bộ nhớ.

Tuy nhiên, C ++ có xu hướng làm cho việc đưa mã và dữ liệu vào FLASH khó khăn hơn, do các quy tắc xây dựng thời gian chạy cho các đối tượng. Trong C, một cấu trúc hằng có thể dễ dàng được đưa vào bộ nhớ FLASH và được truy cập như một đối tượng hằng số phần cứng. Trong C ++, một đối tượng hằng sẽ yêu cầu trình biên dịch đánh giá hàm tạo tại thời điểm biên dịch, điều này tôi nghĩ vẫn còn vượt quá những gì mà trình biên dịch C ++ có thể làm (về mặt lý thuyết, bạn có thể làm điều đó, nhưng nó rất khó thực hiện trong thực tế) .

Vì vậy, trong loại môi trường "RAM nhỏ", "FLASH lớn", tôi sẽ sử dụng C bất cứ ngày nào. Lưu ý rằng một lựa chọn trung gian tốt i C99 có hầu hết các tính năng C ++ tốt cho mã không dựa trên lớp.


3
Có lý do gì tại sao cùng một cấu trúc sẽ được đưa vào bộ nhớ Flash trong C, lại không xuất hiện trong Flash trong C ++? Bạn không cần phải thêm một hàm tạo vào cấu trúc của mình trong C ++.
jalf

1

Nói chung là không. C ++ là một tập hợp siêu C. Điều này đặc biệt đúng đối với các dự án mới.

Bạn đang đi đúng hướng trong việc tránh các cấu trúc C ++ có thể tốn kém về thời gian cpu và bản in bộ nhớ.

Lưu ý rằng một số thứ như đa hình có thể rất có giá trị - về cơ bản là các con trỏ hàm. Nếu bạn thấy bạn cần chúng, hãy sử dụng chúng - một cách khôn ngoan.

Ngoài ra, xử lý ngoại lệ tốt (được thiết kế tốt) có thể làm cho ứng dụng nhúng của bạn đáng tin cậy hơn một ứng dụng xử lý mọi thứ bằng mã lỗi truyền thống.


2
Nói một cách chính xác, C ++ không phải là một tập hợp chính xác của C, nhưng chi tiết cụ thể đó không phải là đặc biệt quan trọng trong bối cảnh này.
Arafangion

1

Đối với vấn đề cấp phát bộ nhớ, tôi có thể khuyên bạn nên sử dụng Nền tảng lượng tử và cách tiếp cận máy trạng thái của nó, vì nó phân bổ mọi thứ bạn cần tại thời điểm khởi tạo. Nó cũng giúp giảm bớt các vấn đề tranh chấp.

Sản phẩm này chạy trên cả C và C ++.


1

Một số người nói rằng trình biên dịch C có thể tạo ra mã hiệu quả hơn nhiều vì chúng không phải hỗ trợ các tính năng C ++ nâng cao và do đó có thể tích cực hơn trong việc tối ưu hóa của chúng.

Tất nhiên, trong trường hợp này, bạn có thể muốn đưa hai trình biên dịch cụ thể vào thử nghiệm.


1
Liên quan: Từ khóa hạn chế theo như tôi biết cấu trúc C liên quan đến tối ưu hóa duy nhất bị thiếu trong C ++ (cũng là C ++ 11).
Johan Lundberg

1

Lý do duy nhất để thích C IMHO sẽ là nếu trình biên dịch C ++ cho nền tảng của bạn không ở trạng thái tốt (lỗi, tối ưu hóa kém, v.v.).


Điều gì về việc sử dụng bộ nhớ / tài nguyên?
Steve Lazaridis

Còn nó thì sao? Không có lý do gì để trình biên dịch C ++ tạo ra mã kém hiệu quả hơn mã C, ngoại trừ trường hợp mã sử dụng RTTI, điều không có trên các hệ thống nhúng.
Nemanja Trifunovic


1

Bạn có nội tuyến trong C99. Có thể bạn thích ctors, nhưng việc kinh doanh để có được dtors phù hợp có thể rất lộn xộn. Nếu lý do duy nhất còn lại để không sử dụng C là không gian tên, tôi thực sự sẽ gắn bó với C89. Điều này là do bạn có thể muốn chuyển nó sang một nền tảng nhúng hơi khác. Sau đó, bạn có thể bắt đầu viết bằng C ++ trên cùng mã đó. Nhưng hãy lưu ý những điều sau đây, trong đó C ++ KHÔNG phải là tập siêu của C. Tôi biết bạn đã nói rằng bạn có trình biên dịch C89, nhưng dù sao thì so sánh C ++ này với C99 cũng vậy, ví dụ như mục đầu tiên đúng với bất kỳ C nào kể từ K&R.

sizeof 'a' > 1 trong C, không phải trong C ++. Trong C, bạn có mảng độ dài thay đổi VLA. Ví dụ: func (int i) {int a [i] . Trong C bạn có các thành viên mảng biến VAM. Ví dụ: struct {int b; int m [];} .


1
Không. Tôi muốn nói rằng trong C bạn có (sizeof 'a') == sizeof (int). Trong khi trong C ++, bạn có 1 == sizeof 'a'
hept

1
Chưa kể "int * a; ...; a = (int *) malloc (size * sizeof (int));" là cách cấp phát bộ nhớ hoạt động trong C và C ++, và không nên được sử dụng trong cả hai. Sử dụng "a = malloc (size * sizeof (int));" hoặc "vector <int> a (size);" hoặc thậm chí "int * a = new int [size];" thay thế.
David Thornley

1
Tôi không hiểu quan điểm của bạn về dtors. Toàn bộ điểm về chúng là chúng làm cho phần còn lại của mã của bạn ít lộn xộn hơn rất nhiều .
jalf

1
+1, không hiểu tại sao bài đăng này lại có đoạn rap tệ như vậy. Nhưng tôi đồng ý với jalf, các trình hủy đơn giản hóa mã một cách mạnh mẽ khi được sử dụng đúng cách (RAII). (Bạn có thể nói rằng họ "làm việc đằng sau hậu trường", nhưng họ chỉ làm những thứ mà mã chính xác sẽ được thực hiện theo cách thủ công.)
j_random_hacker

1
Tôi nghĩ những điều tôi chỉ ra rất liên quan đến câu hỏi. Tôi cũng kiên định với tuyên bố của mình rằng dtors có thể khó, và lý do chính xác là nó tự động xảy ra. Tôi bị trừ điểm - điều đó thực sự đáng ghét. Đoán là vì tôi không nói "CÓ, ĐI C ++ nó TUYỆT VỜI".
hept

1

Nó phụ thuộc vào trình biên dịch.

Không phải tất cả các trình biên dịch nhúng đều triển khai tất cả C ++ và ngay cả khi chúng có, chúng có thể không tốt trong việc tránh mã phồng (luôn là rủi ro với các mẫu). Kiểm tra nó với một vài chương trình nhỏ hơn, xem bạn có gặp phải sự cố nào không.

Nhưng với một trình biên dịch tốt , không, không có lý do gì để không sử dụng C ++.


1

Chỉ muốn nói rằng không có hệ thống nào có tài nguyên "KHÔNG GIỚI HẠN". Mọi thứ trên thế giới này đều có giới hạn và MỌI ứng dụng nên xem xét việc sử dụng tài nguyên cho dù là ASM, C, JAVA hay JavaScript. Các hình nộm phân bổ một vài Mbs "chỉ để chắc chắn" khiến iPhone 7, Pixel và các thiết bị khác trở nên cực kỳ luộm thuộm. Không cần biết bạn có 4kb hay 40 Gb.

Nhưng từ một khía cạnh khác để phản đối việc lãng phí tài nguyên - là một thời gian cần thiết để tiết kiệm những tài nguyên đó. Nếu phải mất thêm 1 tuần để viết một thứ đơn giản bằng C để tiết kiệm một vài tích tắc và một vài byte thay vì sử dụng C ++ đã được triển khai, thử nghiệm và phân phối. Quan tâm làm gì? Nó giống như mua một trung tâm usb. vâng bạn có thể tự làm nhưng liệu nó có tốt hơn không? đáng tin cậy hơn? rẻ hơn nếu bạn tính thời gian của bạn?

Chỉ là một suy nghĩ phụ - ngay cả nguồn điện từ ổ cắm của bạn không phải là không giới hạn. Hãy thử nghiên cứu xem nó đến từ đâu và bạn sẽ thấy phần lớn là do đốt thứ gì đó. Quy luật năng lượng và vật chất vẫn còn nguyên giá trị: không có vật chất hay năng lượng nào xuất hiện hay biến mất mà là biến đổi.


0

Tôi vừa tìm thấy một ví dụ về cách sử dụng ISO C ++ để phát triển nhúng, điều này có thể thú vị đối với ai đó đang đưa ra quyết định bất cứ khi nào sử dụng C ++ hoặc C.

Nó được cung cấp bởi Bjarne Stroustrup tại trang chủ của anh ấy :

Để biết cách ISO C ++ có thể được sử dụng cho lập trình hệ thống nhúng nghiêm túc, hãy xem các tiêu chuẩn mã hóa C ++ trên phương tiện hàng không JSF .


Chà, những thứ bay thường có bộ vi xử lý PPC với bộ nhớ RAM hàng gigabyte. Không phải là hệ thống nhúng hạn chế tài nguyên trung bình của bạn.
jakobengblom2

0

Bài trả lời khác nhau cho một khía cạnh khác của câu hỏi:

"malloc"

Một số bài trả lời trước nói khá nhiều về điều này. Tại sao bạn thậm chí nghĩ rằng cuộc gọi đó tồn tại? Đối với một nền tảng thực sự nhỏ, malloc có xu hướng không có sẵn hoặc chắc chắn là tùy chọn. Việc triển khai phân bổ bộ nhớ động có xu hướng có ý nghĩa khi bạn có RTOS ở cuối hệ thống - nhưng cho đến lúc đó, nó hoàn toàn nguy hiểm.

Bạn có thể đi rất xa nếu không có nó. Chỉ cần nghĩ về tất cả các chương trình FORTRAN cũ thậm chí không có ngăn xếp thích hợp cho các biến cục bộ ...


0

Có một số nhà sản xuất bộ điều khiển khác nhau trên toàn cầu và khi bạn xem xét các thiết kế của họ và các tập lệnh cần được sử dụng để cấu hình, bạn có thể gặp rất nhiều rắc rối. Nhược điểm chính của hợp ngữ là phụ thuộc vào máy / kiến ​​trúc. Nó thực sự rất lớn, yêu cầu một nhà phát triển thuộc lòng tất cả các hướng dẫn đặt ra ở đó để hoàn thành việc mã hóa cho các bộ điều khiển khác nhau. Đó là lý do tại sao C trở nên phổ biến hơn trong phát triển nhúng vì C đủ cấp cao để trừu tượng hóa các thuật toán và cấu trúc dữ liệu từ các chi tiết phụ thuộc vào phần cứng, làm cho mã nguồn có thể di động trên nhiều phần cứng đích, ngôn ngữ độc lập với kiến ​​trúc và rất dễ dàng chuyển đổi và duy trì mã. Nhưng chúng tôi thấy một số ngôn ngữ cấp cao (hướng đối tượng) như C, C ++, Python, Java, v.v.


0

Tôi khuyên bạn nên dùng C ++ với những hạn chế và lưu ý.

  1. Thời gian đưa ra thị trường và khả năng bảo trì. C ++ phát triển dễ dàng hơn và nhanh hơn. Vì vậy, nếu bạn đang trong giai đoạn thiết kế, hãy chọn một bộ điều khiển đủ tốt để sử dụng C ++. (Lưu ý rằng một số thị trường có khối lượng lớn yêu cầu chi phí càng thấp càng tốt, nơi bạn không thể đưa ra lựa chọn này.)

  2. Tốc độ. C có thể nhanh hơn C ++, nhưng hãy chắc chắn rằng tốc độ tăng là không lớn. Vì vậy, bạn có thể sử dụng C ++. Phát triển các thuật toán của bạn, kiểm tra chúng và làm cho chúng nhanh hơn chỉ khi được yêu cầu (!). Sử dụng bộ định hình, để chỉ ra các điểm nghẽn và viết lại chúng theo cách "C" rõ ràng , để đạt được tốc độ C. (Nếu nó vẫn chậm triển khai phần đó trong ASM)

  3. Kích thước nhị phân. Các mã C ++ lớn hơn, nhưng đây là một câu trả lời tuyệt vời cho biết chi tiết. Kích thước của tệp nhị phân đã biên dịch của một mã C nhất định sẽ giống nhau cho dù nó được biên dịch bằng trình biên dịch C hay C ++. "Kích thước thực thi hầu như không liên quan đến ngôn ngữ, nhưng với các thư viện bạn đưa vào dự án của mình." Đến với C ++ nhưng tránh các chức năng tiên tiến, như streams, string, new, virtualchức năng, vv Xem xét tất cả các chức năng thư viện trước khi cho phép chúng trong mã cuối cùng, vì giới hạn kích thước (dựa trên này câu trả lờ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.