Làm việc trong một dự án nhúng, tôi đã thử làm việc trong tất cả C một lần, và chỉ không thể chịu được. Nó chỉ dài dòng đến mức khiến bạn khó đọc bất cứ thứ gì. Ngoài ra, tôi thích các vùng chứa được tối ưu hóa cho nhúng mà tôi đã viết, chúng phải biến thành #define
các khối kém an toàn và khó sửa hơn nhiều .
Mã trong C ++ trông giống như:
if(uart[0]->Send(pktQueue.Top(), sizeof(Packet)))
pktQueue.Dequeue(1);
trở thành:
if(UART_uchar_SendBlock(uart[0], Queue_Packet_Top(pktQueue), sizeof(Packet)))
Queue_Packet_Dequeue(pktQueue, 1)
mà nhiều người có thể sẽ nói là tốt nhưng sẽ thật nực cười nếu bạn phải thực hiện nhiều hơn một vài lệnh gọi "method" trong một dòng. Hai dòng C ++ sẽ biến thành năm dòng C (do giới hạn độ dài dòng 80 ký tự). Cả hai sẽ tạo ra cùng một mã, vì vậy nó không giống như bộ xử lý đích quan tâm!
Một lần (trở lại năm 1995), tôi đã thử viết rất nhiều C cho một chương trình xử lý dữ liệu đa bộ xử lý. Loại mà mỗi bộ xử lý có bộ nhớ và chương trình riêng. Trình biên dịch do nhà cung cấp cung cấp là trình biên dịch C (một số loại dẫn xuất HighC), các thư viện của họ là mã nguồn đóng nên tôi không thể sử dụng GCC để xây dựng và các API của họ được thiết kế với suy nghĩ rằng chương trình của bạn chủ yếu sẽ là quá trình / khởi tạo / chấm dứt sự đa dạng, vì vậy giao tiếp giữa các bộ xử lý tốt nhất là thô sơ.
Tôi đã có khoảng một tháng trước khi từ bỏ, tìm thấy một bản sao của cfront và hack nó vào trang điểm để tôi có thể sử dụng C ++. Cfront thậm chí không hỗ trợ các mẫu, nhưng mã C ++ rõ ràng hơn rất nhiều.
Cấu trúc dữ liệu chung kiểu, an toàn (sử dụng mẫu).
Điều gần nhất mà C có với các mẫu là khai báo một tệp tiêu đề với rất nhiều mã giống như:
TYPE * Queue_##TYPE##_Top(Queue_##TYPE##* const this)
{ }
sau đó kéo nó vào với một cái gì đó như:
#define TYPE Packet
#include "Queue.h"
#undef TYPE
Lưu ý rằng điều này sẽ không hoạt động đối với các loại phức hợp (ví dụ: không có hàng đợi unsigned char
) trừ khi bạn thực hiện typedef
trước.
Ồ, và hãy nhớ rằng, nếu mã này thực sự không được sử dụng ở bất kỳ đâu, thì bạn thậm chí không biết liệu nó có chính xác về mặt cú pháp hay không.
CHỈNH SỬA: Một điều nữa: bạn sẽ cần quản lý việc khởi tạo mã theo cách thủ công . Nếu mã "mẫu" của bạn không phải là tất cả các chức năng nội tuyến, thì bạn sẽ phải đặt một số kiểm soát để đảm bảo rằng mọi thứ chỉ được khởi tạo một lần để trình liên kết của bạn không tạo ra một đống lỗi "nhiều trường hợp của Foo" .
Để làm điều này, bạn sẽ phải đặt nội dung không được nội tuyến trong phần "triển khai" trong tệp tiêu đề của mình:
#ifdef implementation_##TYPE
#endif
Và sau đó, ở một nơi trong tất cả mã của bạn cho mỗi biến thể mẫu , bạn phải:
#define TYPE Packet
#define implementation_Packet
#include "Queue.h"
#undef TYPE
Ngoài ra, phần triển khai này cần phải nằm ngoài tiêu chuẩn #ifndef
/ #define
/ #endif
litany, vì bạn có thể bao gồm tệp tiêu đề mẫu trong tệp tiêu đề khác, nhưng cần phải khởi tạo sau đó trong .c
tệp.
Đúng, nó trở nên xấu đi nhanh chóng. Đó là lý do tại sao hầu hết các lập trình viên C thậm chí không thử.
RAII.
Đặc biệt là trong các hàm có nhiều điểm trả về, ví dụ như không phải nhớ giải phóng mutex trên mỗi điểm trả về.
Chà, quên đoạn mã đẹp đẽ của bạn và làm quen với tất cả các điểm trả về của bạn (ngoại trừ phần cuối của hàm) là goto
:
TYPE * Queue_##TYPE##_Top(Queue_##TYPE##* const this)
{
TYPE * result;
Mutex_Lock(this->lock);
if(this->head == this->tail)
{
result = 0;
goto Queue_##TYPE##_Top_exit:;
}
Queue_##TYPE##_Top_exit:
Mutex_Lock(this->lock);
return result;
}
Kẻ hủy diệt nói chung.
Tức là bạn viết một d'tor một lần cho MyClass, sau đó nếu một cá thể MyClass là thành viên của MyOtherClass, MyOtherClass không phải định nghĩa rõ ràng cá thể MyClass - d'tor của nó được gọi tự động.
Việc xây dựng đối tượng phải được xử lý rõ ràng theo cùng một cách.
Không gian tên.
Đó thực sự là một cách khắc phục đơn giản: chỉ cần gắn một tiền tố vào mỗi biểu tượng. Đây là nguyên nhân chính gây ra hiện tượng phồng nguồn mà tôi đã nói trước đó (vì các lớp là không gian tên ngầm định). Những người C đã sống như vậy, tốt, mãi mãi, và có lẽ sẽ không thấy vấn đề lớn là gì.
YMMV