Tôi đang viết bộ nạp khởi động trong C11. Khi bộ tải khởi động cần truyền điều khiển đến phần sụn, nó sẽ đọc một con trỏ hàm tại địa chỉ bộ nhớ được xác định trước và gọi nó. Mã này trông như thế này:Làm thế nào để sử dụng noreturn với con trỏ hàm?
typedef void (FirmwareBootFn)(void);
typedef struct
{
uint32_t stackPointer;
FirmwareBootFn* programCounter;
}
FirmwareBootControl;
static FirmwareBootControl g_bootControl __attribute__ ((section (".boot_control")));
void
Firmware_boot(void)
{
setStackPointer(g_bootControl.stackPointer);
g_bootControl.programCounter();
}
Chức năng Firmware_boot()
không bao giờ trở lại, vì vậy nó làm cho tinh thần để khai báo nó như noreturn
:
#include <stdnoreturn.h>
noreturn void
Firmware_boot(void);
Nhưng tôi cần phải khai báo FirmwareBootFn
như noreturn
cũng như để tránh các trình biên dịch phàn nàn rằng Firmware_boot()
có thể trở lại.
Tôi đã thử (có thể) mọi hoán vị của noreturn
trong số typedef
mà không có bất kỳ kết quả nào. Ngoài ra tôi hiểu rằng thuộc tính không thể được đặt trong typedef
bởi vì nó không phải là một phần của loại.
Có cách nào để gắn thẻ số Firmware_boot()
của mình là noreturn
tránh cảnh báo (tốt mà không bị gian lận với ngăn chặn cảnh báo :-)) không?
Tôi chỉ tìm thấy giải pháp thay thế cho gcc: sử dụng ** __ builtin_unreachable **() đánh dấu một điểm cụ thể của mã là "dòng này sẽ không bao giờ được thực hiện" do đó cấp thuộc tính noreturn. Mặc dù công trình này, nó không phải là di động và không cho phép trình biên dịch để hiểu rằng (ít nhất là IMO) g_bootControl.programCounter() không trở lại và áp dụng tối ưu hóa thích hợp. – MaxP
@MaxP, cả tài liệu và đầu ra của trình biên dịch của một chương trình thử nghiệm nhỏ dường như chỉ ra nó được sử dụng để tối ưu hóa. (Nếu 'foo' được khai báo' _Noreturn' và 'bar' không phải là' foo(); 'và' bar(); __builtin_unreachable(); 'tạo mã tương đương.) – mafso
Nếu bạn sẵn sàng sử dụng phần mở rộng, sử dụng một 'thuộc tính'. Xin vui lòng xem câu trả lời của tôi. –