Có máy nào, trong đó sizeof (char)! = 1, hoặc ít nhất CHAR_BIT> 8 không?


93

Có máy móc (hoặc trình biên dịch) không, ở đâu sizeof(char) != 1?

Liệu tiêu chuẩn C99 nói rằng sizeof(char)tình hình thực hiện tuân thủ tiêu chuẩn phải được chính xác 1? Nếu đúng, vui lòng cho tôi số phần và trích dẫn.

Cập nhật: Nếu tôi có một máy (CPU) không thể định địa chỉ byte (đọc tối thiểu là 4 byte, được căn chỉnh), nhưng chỉ có 4 byte byte ( uint32_t), trình biên dịch cho máy này có thể xác định sizeof(char)thành 4 không? sizeof(char)sẽ là 1, nhưng char sẽ có 32 bit ( CHAR_BITmacro)

Cập nhật2: Nhưng kết quả sizeof KHÔNG phải là BYTES! nó là kích thước của CHAR. Và char có thể là 2 byte, hoặc (có thể là) 7 bit?

Cập nhật 3: Ok. Tất cả các máy đều có sizeof(char) == 1. Nhưng máy móc có những gì CHAR_BIT > 8?


4
Tôi lo lắng về việc tuân thủ tiêu chuẩn C99. Tôi làm việc chặt chẽ với trình biên dịch C99
osgx

2
Khi Unicode thậm chí còn trở nên quan trọng hơn, có thể có những trình biên dịch không chuẩn sử dụng các ký tự Unicode làm char(thay vì wchar.) Ngay cả khi tiêu chuẩn nói rằng sizeof(char)phải là 1, tôi sẽ không dựa vào giả định đó.
Chip Uni

14
không có trình biên dịch C nào mà sizeof (char) không phải là 1, unicode hay không.
nos

6
@Chip: sizeof(char)luôn là 1, ngay cả khi char là 32-bit (như xảy ra trên một số hệ thống). C có rất nhiều mụn cóc vui nhộn.
Nick Bastin

2
Tất cả các phiên bản của tiêu chuẩn C đều yêu cầu CHAR_BIT tối thiểu là 8; bạn không thể có CHAR_BIT == 7 và tuân thủ tiêu chuẩn. Tuy nhiên, hoàn toàn khả thi đối với các máy có CHAR_BIT> 8. Các máy Cray cũ đã làm được điều đó, tôi tin rằng ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)về những điều đó, tôi không nhớ sizeof(int) == sizeof(long)liệu CHAR_BIT là 32 hay 64; tôi mong đợi nó là 32 và tôi cũng nghĩ sizeof(long) == 1vậy. (Bạn có thể tìm thấy một tham chiếu đến, nhưng truy cập không trực tuyến để, một tay Cray C ).
Jonathan Leffler

Câu trả lời:


91

Nó luôn là một trong C99, phần 6.5.3.4:

Khi áp dụng cho một toán hạng có kiểu char, unsigned char, hoặc sign char, (hoặc phiên bản đủ điều kiện của chúng), kết quả là 1.

Chỉnh sửa: không phải là một phần của câu hỏi của bạn, nhưng vì sự quan tâm của Harbison và Steele, xuất bản lần thứ 3. (trước c99) tr. 148:

Một đơn vị lưu trữ được coi là dung lượng lưu trữ được chiếm bởi một ký tự; do đó kích thước của một đối tượng kiểu charlà 1.

Chỉnh sửa: Để trả lời cho câu hỏi cập nhật của bạn, câu hỏi và câu trả lời sau đây của Harbison và Steele là có liên quan (sđd, ví dụ: 4 của Ch. 6):

Có được phép triển khai C trong đó kiểu charcó thể đại diện cho các giá trị từ -2,147,483,648 đến 2,147,483,647 không? Nếu vậy, những gì sẽ được sizeof(char) thực hiện theo? Phạm vi loại nhỏ nhất và lớn nhất sẽ là intgì?

Trả lời (sđd, tr. 382):

Được phép (nếu lãng phí) khi triển khai sử dụng 32 bit để biểu diễn kiểu char. Bất kể việc triển khai như thế nào, giá trị của sizeof(char)luôn là 1.

Mặc dù điều này không giải quyết cụ thể trường hợp, ví dụ byte là 8 bit và charlà 4 trong số các byte đó (thực sự là không thể với định nghĩa c99, xem bên dưới), thực tế là sizeof(char) = 1luôn rõ ràng so với tiêu chuẩn c99 và Harbison và Steele.

Chỉnh sửa: Thực tế (đây là câu trả lời cho câu hỏi cập nhật 2 của bạn), theo như c99 có liên quan sizeof(char) byte, từ phần 6.5.3.4 một lần nữa:

Toán tử sizeof mang lại kích thước (tính bằng byte) cho toán hạng của nó

vì vậy kết hợp với phần trích dẫn ở trên, byte 8 bit và char4 byte trong số đó là không thể: đối với c99, một byte giống như a char.

Để trả lời cho đề cập của bạn về khả năng có 7 bit char: điều này là không thể trong c99. Theo mục 5.2.4.2.1 của tiêu chuẩn, mức tối thiểu là 8:

Các giá trị được xác định bằng cách triển khai của chúng sẽ bằng hoặc lớn hơn [sự nhấn mạnh của tôi] về độ lớn so với những giá trị được hiển thị, có cùng dấu hiệu.

- số bit cho đối tượng nhỏ nhất không phải là trường bit (byte)

 **CHAR_BIT 8**

- giá trị tối thiểu cho một đối tượng kiểu ký hiệu char

**SCHAR_MIN -127//−(27−1)** 

- giá trị lớn nhất cho một đối tượng kiểu ký hiệu char

**SCHAR_MAX +127//27−1** 

- giá trị lớn nhất cho một đối tượng kiểu unsigned char

**UCHAR_MAX 255//28−1** 

- giá trị tối thiểu cho một đối tượng kiểu char

**CHAR_MIN**    see below 

- giá trị lớn nhất cho một đối tượng kiểu char

**CHAR_MAX**    see below

[...]

Nếu giá trị của một đối tượng kiểu char được coi là số nguyên có dấu khi được sử dụng trong một biểu thức, thì giá trị của CHAR_MIN sẽ giống với giá trị của SCHAR_MIN và giá trị của CHAR_MAX sẽ giống như giá trị của SCHAR_MAX. Nếu không, giá trị của CHAR_MIN sẽ là 0 và giá trị của CHAR_MAX sẽ giống như giá trị của UCHAR_MAX. Giá trị UCHAR_MAX sẽ bằng 2 ^ CHAR_BIT - 1.


9
Ghi chú bổ sung. có một macro CHAR_BITS sẽ cho bạn biết ký tự của bạn có bao nhiêu bit.
nos

1
Dữ liệu đầy đủ của cuốn sách tuyệt vời này là của Harbison và Steele. C: Sách hướng dẫn tham khảo, Ấn bản thứ ba, Prentice Hall, 1991
osgx

2
Nếu bạn biết rằng bạn đang làm việc với các loại char và bạn biết ngôn ngữ yêu cầu chúng phải có kích thước là 1, tại sao bạn nên luôn đặt kích thước dư thừa (char)?

1
(a) và (c) có nhiều phân nhánh nghiêm trọng hơn mà điều này không thể hy vọng giải quyết được, hoặc thậm chí gần với việc giải quyết; cũng YAGNI. Ai đó như trong (b) chỉ cần được nói một lần --- Tôi không cần phải dạy họ trong mỗi dòng mã của tôi. Tuy nhiên, có những hạn chế khi sử dụng sizeof(char): đó là một mục khác để tranh luận / kiểm tra / vv. trong các quy ước / tiêu chuẩn / hướng dẫn về mã hóa của bạn, làm tôi lãng phí thời gian khi tự hỏi liệu bạn có thực sự biết C hay không và những gì khác có thể không chính xác, chiếm băng thông "" hình ảnh / tinh thần / dòng văn bản.

1
@Ramashalanka: Có, mã đã biên dịch là tương đương. Đó là tất cả các vấn đề xung quanh khả năng đọc và cách mọi người sử dụng mã nguồn mà tôi đang nói đến. (Và FWIW, tôi nghĩ bạn có một câu trả lời +1 phù hợp ở đây, tôi chỉ thấy "luôn sử dụng sizeof (char)" là sai lầm và là một vấn đề nóng đối với tôi, ngay cả khi một vấn đề nhỏ.)

21

Không có máy nào ở đó sizeof(char)là 4. Nó luôn luôn là 1 byte. Byte đó có thể chứa 32 bit, nhưng đối với trình biên dịch C, nó là một byte. Để biết thêm chi tiết, tôi thực sự sẽ hướng dẫn bạn tại Câu hỏi thường gặp về C ++ 26.6 . Liên kết đó bao gồm nó khá tốt và tôi khá chắc chắn C ++ có tất cả các quy tắc đó từ C. Bạn cũng có thể xem Câu hỏi thường gặp về comp.lang.c 8.10 cho các ký tự lớn hơn 8 bit.

Upd2: Nhưng kết quả sizeof KHÔNG phải là BYTES! nó là kích thước của CHAR. Và char có thể là 2 byte, hoặc (có thể là) 7 bit?

Vâng, nó là byte. Hãy để tôi nói lại lần nữa. sizeof(char)là 1 byte theo trình biên dịch C. Những gì mọi người gọi một cách thông tục là một byte (8 bit) không nhất thiết phải giống với những gì mà trình biên dịch C gọi là một byte. Số lượng bit trong một byte C khác nhau tùy thuộc vào kiến ​​trúc máy của bạn. Nó cũng được đảm bảo ít nhất là 8.


3
Xin vui lòng!!! C ++ là ngôn ngữ thực sự KHÁC BIỆT so với C (C99). Câu hỏi này chỉ nói về C đơn giản.
osgx

<strike> Tôi có thể làm gì khi máy / CPU không thể truy cập byte 8-bit? Truy cập không được căn chỉnh bị cấm. </strike> (Ngay cả trên x86, malloc trả về dữ liệu đã căn chỉnh và cấp phát bộ nhớ theo số nhân của 4 byte.) <strike> Khi đó CHAT_BIT sẽ lớn hơn 8. Có, nền tảng như vậy có thể khá đặc biệt. </ Strike >
osgx

10
@osgx, tôi có xu hướng hét lên nhiều như bạn vừa làm khi mọi người cố gắng trộn C và C ++. Nhưng tôi nghĩ rằng trong trường hợp này là một trong C ++ mục Hỏi đáp áp dụng tốt như nhau để C.
Michael Kristofik

3
Tên chính xác cho "8 bit" là octet. Tiêu chuẩn C sử dụng từ "byte" cho một đối tượng có kích thước bằng một ký tự. Những người khác có thể sử dụng từ "byte" theo nhiều cách khác nhau, thường khi chúng có nghĩa là "octet", nhưng trong C (và C ++, hoặc Objective-C) nó có nghĩa là "đối tượng có kích thước bằng một ký tự". Một ký tự có thể nhiều hơn 8 bit hoặc nhiều hơn một octet, nhưng nó luôn là một byte.
gnasher729

9

PDP-10 và PDP-11 là.

Cập nhật: không có trình biên dịch C99 nào cho PDP-10.

Một số mô hình của Analog Devices 32-bit SHARC DSP có CHAR_BIT = 32, và Texas Instruments DSP từ TMS32F28xx có CHAR_BIT = 16, báo cáo .

Cập nhật: Có GCC 3.2 cho PDP-10 với CHAR_BIT = 9 (kiểm tra bao gồm / giới hạn.h trong kho lưu trữ đó).


1
Đừng nhầm lẫn việc triển khai các ngôn ngữ tương tự nhưng không-C với C. Bạn thậm chí còn nói "Tôi lo lắng về việc tuân thủ tiêu chuẩn C99. Tôi làm việc chặt chẽ với các trình biên dịch C99."

2
@Roger: Không công bằng khi gọi GCC3 không tuân thủ C99 trừ khi bạn đang xử lý các trường hợp cực đoan được coi là lỗi trong GCC.
Joshua

1
@Joshua, tôi nghĩ Roger nói về K&R và trình biên dịch lịch sử pcc. Cũng không công bằng khi tuyên bố nó tuân thủ C99 trước khi testsuite tuân thủ C99 được chạy trên PDP-10, khi được biên dịch với cổng này (có thể có lỗi từ quá trình chuyển và từ chính máy). Nhưng nó có thể được mong đợi là gần với tiêu chuẩn C99 cũng như GCC3.2 trên x86.
osgx

1
@Joshua: Trong C99, CHAR_BIT được phép lớn hơn 8, nhưng sizeof (char) vẫn phải là 1 (và câu trả lời này khác nhiều khi tôi để lại nhận xét đó). Tôi không gọi GCC3 là không tuân thủ và C89 đưa ra yêu cầu tương tự ở đây, BTW. Tôi đã trích dẫn văn bản đó để nói rằng osgx là người lo lắng về khả năng tuân thủ C99 và sử dụng các trình biên dịch C99, vậy tại sao anh ta lại lo lắng về các trình biên dịch không phải C99?

2
Tác giả của PDP-10 GCC tại đây. CHAR_BIT là 9, nhưng sizeof (char) vẫn là 1.
Lars Brinkhoff
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.