2009-10-08 40 views
7

Khi trả lời nhận xét cho câu trả lời khác của tôi here, tôi đã tìm thấy những gì tôi nghĩ rằng có thể là một lỗ trong tiêu chuẩn C (c1x, tôi chưa kiểm tra các phiên bản trước đó và vâng, tôi biết nó là vô cùng khó mà tôi một mình trong số tất cả cư dân của hành tinh đã tìm thấy một lỗi trong tiêu chuẩn). Thông tin sau:Vấn đề tiềm ẩn với ký tự chuẩn malloc'ing C

  1. Mục 6.5.3.4 ("Toán tử sizeof") cho 2 tiểu bang "The sizeof operator yields the size (in bytes) of its operand".
  2. Para 3 trong số đó cho biết: "When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1".
  3. Mục 7.20.3.3 mô tả void *malloc(size_t sz) nhưng tất cả điều đó nói là "The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate". Nó làm cho không có đề cập đến ở tất cả các đơn vị được sử dụng cho các đối số.
  4. Phụ lục E bắt đầu số 8 là tối thiểu giá trị cho CHAR_BIT để ký tự có thể dài hơn một byte.

Câu hỏi của tôi chỉ đơn giản là thế này:

Trong một môi trường mà một char là 16 bit rộng, sẽ malloc(10 * sizeof(char)) phân bổ 10 ký tự (20 byte) hoặc 10 byte? Điểm 1 ở trên dường như chỉ ra điểm cũ, điểm 2 cho biết điểm thứ hai.

Bất kỳ ai có nhiều C-standard-fu hơn tôi đều có câu trả lời cho điều này?

Trả lời

16

Trong một 16-bit char môi trường malloc(10 * sizeof(char)) sẽ phân bổ 10 char s (10 byte), bởi vì nếu char là 16 bit, sau đó rằng kiến ​​trúc/thực hiện định nghĩa một byte 16 bit. A char không phải là một octet, nó là một byte. Trên các máy tính cũ hơn, điều này có thể lớn hơn 8 bit de-facto tiêu chuẩn chúng tôi có ngày hôm nay.

Các phần có liên quan từ các tiêu chuẩn C sau:

3,6 Điều khoản này, định nghĩa và biểu tượng

byte - đơn vị địa chỉ lưu trữ dữ liệu đủ lớn để chứa bất kỳ thành viên của bộ ký tự cơ bản của việc thực hiện môi trường ...

CHÚ THÍCH 2 - Một byte bao gồm một chuỗi liên tiếp các bit, số đó được xác định thực hiện.

+1

Thực ra, tôi nghĩ bạn có thể có nó ở đó. dựa trên câu trả lời của bạn, tôi tìm thấy 3.6 (trong "Điều khoản, định nghĩa và ký hiệu") nêu rõ "đơn vị lưu trữ dữ liệu byte địa chỉ đủ lớn để giữ bất kỳ thành viên nào của bộ ký tự cơ bản của môi trường thực thi ... CHÚ THÍCH 2 - A byte bao gồm một chuỗi liên tiếp các bit, số lượng được xác định thực hiện ". – paxdiablo

+0

Chết tiệt, hãy suy nghĩ về vinh quang và giải thưởng mà tôi đã nhận được để tìm ra một vấn đề trong tiêu chuẩn. Ồ, quay trở lại công việc ban ngày :-) – paxdiablo

+0

Một lần nữa, tôi thấy mình lặp lại câu thần chú "Tôi cần lấy một bản sao tiêu chuẩn". Tôi sẽ thêm báo giá tiêu chuẩn của bạn vào câu trả lời của tôi cho sự hoàn chỉnh. –

1

Không phải đơn vị của "size_t sz" trong bất kỳ đơn vị địa chỉ nào của kiến ​​trúc của bạn là? Tôi làm việc với một DSP có địa chỉ tương ứng với giá trị 32 bit, không phải byte. malloc (1) cho tôi một con trỏ đến một khu vực 4 byte.

+1

Xét về từ ngữ trong tiêu chuẩn C, một "byte" trên kiến ​​trúc đó là 32 bit. Điều hơi khó hiểu là những gì tiêu chuẩn C gọi là một "byte" không nhất thiết phải tương ứng với (ngày nay) sử dụng phổ biến của từ này. – caf

+1

Và vì lý do tương tự, khi tiêu chuẩn mạng có nghĩa là "8 bit", họ nói "octet", không phải "byte". Nó chỉ trong bối cảnh bán lẻ mà một byte là rõ ràng 8 bit, như trong "MB của băng thông", "GB RAM", "TB của không gian đĩa". –

+0

Ah, điều đó có ý nghĩa. Tôi đoán chúng tôi đang mắc kẹt với sự mơ hồ đối với các luật sư không phải ngôn ngữ, vì những từ như "megaoctets" hoặc "kibioctets" không chảy tốt lắm. – twon33

2

Trong tiêu chuẩn C99 mối tương quan chặt chẽ giữa byte, char, và kích thước đối tượng được đưa ra trong 6.2.6.1/4 "Đại diện của các loại - General":

giá trị được lưu trữ trong các đối tượng không chút-field- của bất kỳ loại đối tượng nào khác bao gồm các bit n × CHAR_BIT, trong đó n là kích thước của một đối tượng thuộc loại đó theo byte. Giá trị có thể được sao chép vào một đối tượng thuộc loại unsigned char [n] (ví dụ: theo memcpy); tập kết quả của byte được gọi là biểu diễn đối tượng của giá trị.

Trong tiêu chuẩn C++ mối quan hệ tương tự được đưa ra trong 3.9/2 "loại":

Đối với bất kỳ đối tượng (trừ một subobject cơ sở-class) của loại POD T, hay không đối tượng giữ một giá trị hợp lệ của kiểu T, các byte bên dưới (1.7) tạo thành đối tượng có thể được sao chép vào một mảng char hoặc unsigned char. Nếu nội dung của mảng char hoặc unsigned char được sao chép trở lại vào đối tượng, đối tượng sau đó sẽ giữ giá trị ban đầu của nó.

Trong C90 có vẻ không được như đã đề cập một cách rõ ràng sự tương quan, nhưng giữa các định nghĩa của một byte, định nghĩa về một nhân vật, và định nghĩa của các nhà điều hành sizeof suy luận có thể được thực hiện mà một loại char tương đương với một byte.

Cũng lưu ý rằng số lượng bit trong một byte (và số bit trong một char) được thực hiện được xác định — nghiêm chỉnh nói rằng nó không cần phải là 8 bit. Và onebyone chỉ ra trong một nhận xét ở nơi khác rằng DSP thường có byte với một số bit không phải là 8.

Lưu ý rằng IETF RFC và tiêu chuẩn nói chung (luôn luôn?) Sử dụng cụm từ 'octect' thay vì 'byte' rõ ràng rằng các đơn vị mà họ đang nói về có chính xác 8 bit - không nhiều hơn, không kém.

+0

+1. Điều đáng nói đến là tiêu chuẩn đặt giới hạn * thấp hơn * của CHAR_BITS nhưng không đặt ở trên. Vì vậy, nó phải có ít nhất 8. – paxdiablo

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