2015-06-17 14 views
6

Tôi đã viết một thư viện bằng C mà giờ đây sẽ được sử dụng trong bảng mạch xử lý được nhúng. Tôi cần phải giảm bộ nhớ chân in như vậy đã đi một thay đổi kiểu trả về của một số chức năng từ int để char (chỉ được sử dụng để cờ lỗi).cảnh báo gcc đối với loại trả lại khác nhau

Thay đổi loại trả về nhưng không thay đổi biến trả lại không tạo ra cảnh báo. Có một số cách thiết lập này trong gcc như tôi muốn đảm bảo tôi đã bắt tất cả các trường hợp.

char processSomething (SomeType *something) 
{ 
    int result = 0; 
    ... 
    do stuff 
    ... 

    return result; /* no warning */ 
} 

Cảm ơn

Tháng Sáu 19: Tôi đã thêm -Wconversion đó đã nêu bật một số điều thú vị. Hai câu hỏi với điều này. Một trong các hàm của tôi, tôi lấy một chuỗi ký tự hai ký tự và chuyển đổi sang thập phân bằng cách sử dụng

char decimal;

decimal = hexstring [0] - '0' << 4 + hexstring [1] - '0'; // for 0 to 9 

nó than phiền về chuyển đổi từ int để char và từ những gì tôi có thể thu thập là '-' nhà khai thác, '+', và '< <' tất cả dường như ngầm chuyển đổi sang int. Đây có phải là chính xác hoặc tôi giải thích cảnh báo sai. Hoặc là có một cách tốt hơn để làm điều này?

Ngoài ra, khi sử dụng strtol vào một int (phàn nàn về 'long int' to 'int') nhưng tôi có thể đảm bảo giá trị sẽ không vượt quá kích thước ngắn gọn, có an toàn để định kiểu không? Như trong nó sẽ cắt ngắn thêm (và hy vọng không byte) của dài? Hay điều này phụ thuộc vào tính cuối cùng?

Cảm ơn

+0

Giá trị trả về hàm sẽ nằm trong sổ đăng ký. Bạn đã không nói bộ xử lý nào, câu hỏi của bạn chỉ có ý nghĩa nếu đó là một 8-bit. –

+0

Lưu ý rằng 'char' có thể được ký hoặc chưa ký! Tốt hơn chỉ định rõ ràng. Sử dụng tốt nhất 'uint8_t' hoặc' int8_t' từ 'stdint.h' Đặc biệt đối với các thiết bị nhúng, đây là cách được khuyến nghị. – Olaf

+3

Tôi nghi ngờ làm điều này sẽ giúp bạn giảm thiểu việc sử dụng bộ nhớ. – HuStmpHrrr

Trả lời

7

Trong trường hợp cụ thể này -Wconversion nên cung cấp cho bạn những cảnh báo mà bạn muốn, trong trường hợp thử nghiệm đơn giản của tôi (see it live):

char func() 
{ 
    int x = 10 ; 

    return x ; 
} 

int main() {} 

tôi nhận được cảnh báo sau đây:

Cảnh báo

: chuyển đổi thành 'char' từ 'int' có thể thay đổi giá trị của nó [-Wconversion]

2

Đây là một ý tưởng thực sự xấu: char là một kích thước nhất định trên hệ thống nhúng nhất (thường là 1 byte, vì thế nó thực sự là một unsigned char) và nếu bạn kết thúc việc thiết int result = 256 của bạn bằng cách nào đó, nó sẽ tràn và trở về 0. lỗi của bạn vừa biến thành một thành công. Crashy crashy (hy vọng). Tồi tệ hơn, có thể giết người nào đó bằng thiết bị được nhúng của bạn.

Tôi biết bạn đang cố khắc phục điều này nhưng thậm chí chỉ cần trả lại số ma thuật là nguy hiểm.

Thay vào đó, hãy khai báo kiểu liệt kê là lỗi. Nó sẽ cung cấp cho bạn loại an toàn (đến một mức độ) và tự động tạo ra kích thước trả lại chính xác cho các chức năng của bạn.

typedef enum status { 
    STATUS_OK = 0, 
    STATUS_ERR1, 
    STATUS_ERR2, 
// ... etc ... 
} status_t; 

status_t processSomething (SomeType *something) 
{ 
    status_t result = STATUS_OK; 
    ... 
    do stuff 
    ... 

    return result; 
} 

Điều này an toàn hơn nhiều và trình biên dịch sẽ chỉ phân bổ 1 byte cho đến khi bạn có quá nhiều thứ để phù hợp và chỉ sau đó nó sẽ lớn hơn. Lấy từ Tiêu chuẩn C hiện tại (C99): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2 Thông số liệt kê [...] Ràng buộc Biểu thức xác định giá trị của hằng số liệt kê phải là biểu thức hằng số nguyên có giá trị biểu thị làm int. [...] Mỗi loại được liệt kê phải tương thích với char, loại số nguyên đã ký hoặc loại số nguyên không dấu. Lựa chọn loại là được xác định thực hiện, nhưng phải có khả năng đại diện cho các giá trị của tất cả các thành viên của điều tra.

+1

'char' không được định nghĩa để ký hoặc không được ký bởi tiêu chuẩn. Nó thậm chí có thể thay đổi giữa các trình biên dịch cho cùng một kiến ​​trúc unles chúng sử dụng cùng một ABI/PCS. Một 'enum' OTOH sẽ là một' int' ít nhất. Điều đó sẽ không cứu được gì cả. (Tuy nhiên, nó là một ý tưởng tốt để có các giá trị trả về như là enums như vậy nếu đó là cho một mã lỗi). – Olaf

+0

Enums không phải là "ít nhất một int" nhưng tại "hầu hết một int", ít nhất đó là sự hiểu biết của tôi từ đây: http://stackoverflow.com/a/366026/951784 – rost0031

+0

Tôi thích [tiêu chuẩn] (http://port70.net/~nsz/c/c11/n1570.html#6.7.2.2p3) làm tài liệu tham khảo. Lưu ý rằng p4 chỉ đề cập đến _compatibility. Đó là lý do tại sao tôi sẽ trả về '(u) int8_t', nhưng sử dụng nhãn enum. – Olaf

Các vấn đề liên quan