Khi xem lại mã, tôi áp dụng các quy tắc sau:
Luôn sử dụng const
cho các tham số chức năng được truyền bởi tham chiếu trong đó chức năng không sửa đổi (hoặc miễn phí) dữ liệu được trỏ đến.
int find(const int *data, size_t size, int value);
Luôn sử dụng const
cho các hằng số có thể được xác định bằng cách sử dụng #define hoặc enum. Trình biên dịch có thể định vị dữ liệu trong bộ nhớ chỉ đọc (ROM) do kết quả (mặc dù trình liên kết thường là một công cụ tốt hơn cho mục đích này trong các hệ thống nhúng).
const double PI = 3.14;
Không bao giờ sử dụng const trong một nguyên mẫu hàm cho một tham số được truyền bởi
giá trị . Nó không có ý nghĩa và do đó chỉ là 'tiếng ồn'.
// don't add const to 'value' or 'size'
int find(const int *data, size_t size, const int value);
Khi thích hợp, sử dụng const volatile
trên các vị trí không thể thay đổi bởi chương trình nhưng vẫn có thể thay đổi. Các thanh ghi phần cứng là trường hợp sử dụng điển hình ở đây, ví dụ một thanh ghi trạng thái phản ánh trạng thái thiết bị:
const volatile int32_t *DEVICE_STATUS = (int32_t*) 0x100;
Sử dụng khác là tùy chọn. Ví dụ, các tham số cho một chức năng trong quá trình thực hiện chức năng có thể được đánh dấu là const.
// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)
{
... etc
hoặc các giá trị trả về hàm hoặc các phép tính thu được và sau đó không bao giờ thay đổi:
char *repeat_str(const char *str, size_t n)
{
const size_t len = strlen(str);
const size_t buf_size = 1 + (len * n);
char *buf = malloc(buf_size);
...
Những cách sử dụng này const
chỉ cho thấy rằng bạn sẽ không thay đổi biến; họ không thay đổi cách thức hoặc nơi lưu trữ biến. Trình biên dịch tất nhiên có thể tìm ra rằng một biến không bị thay đổi, nhưng bằng cách thêm const
bạn cho phép nó thực thi điều đó. Điều này có thể giúp người đọc và thêm một số an toàn (mặc dù nếu các chức năng của bạn đủ lớn hoặc phức tạp đến mức điều này tạo ra sự khác biệt lớn, bạn có thể có vấn đề khác). Chỉnh sửa - ví dụ. một hàm dày đặc 200 dòng với các vòng lặp lồng nhau và nhiều tên biến dài hoặc tương tự nhau, biết rằng các biến nhất định không bao giờ thay đổi có thể dễ dàng hiểu rõ hơn. Các chức năng như vậy đã được thiết kế xấu hoặc duy trì.
Vấn đề với const
. Bạn có thể sẽ nghe thấy thuật ngữ "ngộ độc const". Điều này xảy ra khi thêm const
vào một tham số chức năng khiến 'constness' lan truyền.
Chỉnh sửa - const độc: ví dụ trong chức năng:
int function_a(char * str, int n)
{
...
function_b(str);
...
}
nếu chúng ta thay đổi str
thành const
, chúng ta phải đảm bảo rằng fuction_b
cũng mất một const
. Và như vậy nếu function_b
vượt qua str
vào function_c
, vv Như bạn có thể tưởng tượng này có thể là đau đớn nếu nó truyền thành nhiều file riêng biệt / modules. Nếu nó truyền vào một chức năng không thể thay đổi (ví dụ: thư viện hệ thống), thì việc truyền diễn viên trở nên cần thiết. Vì vậy, rắc
const
xung quanh trong mã hiện tại có lẽ là yêu cầu rắc rối. Trong mã mới, tốt nhất là const
đủ điều kiện nhất quán khi thích hợp.
Vấn đề khó hiểu hơn const
là nó không có trong ngôn ngữ gốc. Là một tiện ích bổ sung, nó không phù hợp lắm. Để bắt đầu, nó có hai ý nghĩa (như trong các quy tắc ở trên, có nghĩa là "Tôi sẽ không thay đổi điều này" và "điều này không thể sửa đổi"). Nhưng hơn thế, nó có thể nguy hiểm. Ví dụ, biên dịch và chạy mã này và (tùy thuộc vào trình biên dịch / tùy chọn), nó có thể bị sập khi chạy:
const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '\0';
strchr
trả về char*
không a const char*
. Vì tham số cuộc gọi của nó là
const
nó phải truyền tham số cuộc gọi đến char*
. Và trong trường hợp này, bỏ đi tài sản lưu trữ chỉ đọc thực sự. Chỉnh sửa: - điều này thường áp dụng cho các vars trong bộ nhớ chỉ đọc. Theo 'ROM', ý tôi không chỉ là ROM vật lý mà là bất kỳ bộ nhớ nào được bảo vệ chống ghi, như xảy ra với phần mã của các chương trình chạy trên một HĐH thông thường.
Nhiều hàm thư viện chuẩn hoạt động theo cùng một cách, vì vậy hãy cẩn thận: khi bạn có các hằng số thực (nghĩa là được lưu trữ trong ROM), bạn phải rất cẩn thận để không bị mất hằng số.
Specific issues with software development
. Tôi đang khá cụ thể.