2015-06-15 14 views
10

Theo the C standard, bất kỳ ký tự nào được trả về bởi fgetc được trả lại ở dạng unsigned char giá trị, "được chuyển đổi thành một tiêu chuẩn C, nói rằng có thực sự là một chuyển đổi).Có thể triển khai có sizeof (int) == 1 "hoàn toàn phù hợp" không?

Khi sizeof (int) == 1, nhiều giá trị unsigned char nằm ngoài phạm vi. Do đó, có thể một số giá trị unsigned char có thể sẽ được chuyển thành giá trị int (kết quả của chuyển đổi là "implementation-defined or an implementation-defined signal is raised") của EOF, sẽ được trả lại mặc dù tệp không thực sự nằm trong tệp sai hoặc cuối tệp tiểu bang.

Tôi rất ngạc nhiên khi thấy rằng triển khai như vậy thực sự tồn tại. Tài liệu TMS320C55x CCS manualUCHAR_MAX có giá trị tương ứng là 65535, INT_MAX có 32767, fputsfopen hỗ trợ chế độ nhị phân ... Điều gì thậm chí còn đáng ngạc nhiên hơn là nó mô tả môi trường hoàn toàn phù hợp, thực hiện đầy đủ (trừ tín hiệu).

Các C55x C/C++ biên dịch hoàn toàn phù hợp với tiêu chuẩn ISO C theo quy định của đặc điểm kỹ thuật ISO ...

Trình biên dịch các công cụ đi kèm với một thư viện runtime hoàn tất. Tất cả các chức năng của thư viện đều tuân theo tiêu chuẩn thư viện ISO C. ...

Thực hiện như vậy có thể trả lại giá trị cho biết lỗi không có, thực sự hoàn toàn phù hợp? Điều này có thể biện minh bằng cách sử dụng feofferror trong phần điều kiện của một vòng lặp (có vẻ ghê gớm như vậy) không? Ví dụ, while ((c = fgetc(stdin)) != EOF || !(feof(stdin) || ferror(stdin))) { ... }

+3

@BLUEPIXY Một "byte" trong tiêu chuẩn là bất kể 'char' là gì. Nó không nhất thiết phải 8 bit. –

+0

Tôi bối rối, nếu 'sizeof (int)' là '1', thì' INT_MAX' là '32767' như thế nào? giá trị đó yêu cầu hai byte 8 bit. Và thực tế, một byte có thể lớn hơn 8 bit, do đó macro 'CHAR_BIT' được sử dụng để xác định. –

+3

@iharob Hệ thống này không sử dụng byte 8 bit. – duskwuff

Trả lời

2

Chức năng fgetc() trả về một giá trị int trong khoảng unsigned char chỉ khi một nhân vật thích hợp được đọc, nếu không nó sẽ trả về EOF đó là một giá trị tiêu cực của loại int.

Câu trả lời ban đầu của tôi (tôi đã thay đổi) giả định rằng có một chuyển đổi số nguyên thành int, nhưng đây không phải là trường hợp, vì thực tế chức năng fgetc() đã trả lại giá trị loại int.

Tôi nghĩ rằng, để phù hợp, việc triển khai phải thực hiện fgetc() để trả về các giá trị không âm trong phạm vi int, trừ khi EOF được trả lại.

Bằng cách này, phạm vi giá trị từ 32768 đến 65535 sẽ không bao giờ được liên kết với mã ký tự trong triển khai TMS320C55x.

+0

Đạo cụ để xem vấn đề ở đây. Việc triển khai cụ thể đó có thể vi phạm hợp đồng 'fgetc' hoặc bằng cách trả lại giá trị âm khi không nên hoặc không hỗ trợ tệp nhị phân chính xác ... – Sebivor

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