Điều gì xác định sizeof (int)


7

Về các kiểu dữ liệu tiêu chuẩn, kích thước của một số nguyên trong bộ điều khiển ATmega là bao nhiêu? Và những gì xác định kích thước, nó chỉ là trình biên dịch? Hoặc là trong thiết kế phần cứng của chính bộ điều khiển và do đó tất cả các trình biên dịch ATmega phải tuân theo kích thước đó? Và nếu nó nằm trong phần cứng, tại sao trong PC bạn có thể có hai trình biên dịch khác nhau cho kết quả khác nhau cho sizeof (int) ngay cả khi chúng chạy trên cùng một bộ xử lý?


4
Trình biên dịch nào.
Tom Carpenter

1
Trình biên dịch có chiều rộng cố định cho int. Trình biên dịch tuân thủ tiêu chuẩn phải sử dụng độ rộng tối thiểu cho int (16 bit) nhưng không có tối đa, vì vậy hai trình biên dịch tuân thủ có thể sử dụng các độ rộng khác nhau ngay cả khi chúng đang phát mã cho cùng một nền tảng.
Spehro Pefhany

@SpehroPefhany Tôi muốn nói rằng: "Trình biên dịch biết kích thước khi biên dịch." - Nó có thể thay đổi theo nền tảng mục tiêu, và có những thứ như -mint8. Vì vậy, kích thước thực tế phụ thuộc, nhưng trình biên dịch chắc chắn biết / quyết định về nó tại thời gian biên dịch.
JimmyB

Nếu câu hỏi của bạn đã được trả lời, bạn có thể vui lòng đánh dấu một trong những câu trả lời là được chấp nhận không?
Alexander - Tái lập Monica

Câu trả lời:


12

intlà loại C. Các ATMega không có khái niệm về nó, chúng chỉ hoạt động với byte 8 bit (vì chúng có CPU AVR 8 bit).

Trình biên dịch chuyển đổi bất kỳ hoạt động nào trên intcác loại thành các hoạt động tương đương cần thiết để thực hiện thao tác đó ở mức kích thước theo yêu cầu của kiến ​​trúc CPU - đối với một AVR, nó được chuyển đổi để thực hiện các hoạt động ở mức byte, đối với CPU 16 bit, nó sẽ được thực hiện tại mức 16 bit, v.v.

Trong avr-gccmột intkiểu được định nghĩa đơn giản trong trình biên dịch là số nguyên 2 byte . Thực tế là nó thay đổi dựa trên nền tảng có nghĩa là bạn tốt hơn khi sử dụng các <stdint.h>loại như uint16_tnếu bạn muốn chắc chắn về kích thước trong mã cần phải di động. Có các loại được xác định cho tất cả các kích thước nguyên tiêu chuẩn (8,16,32,64) ở cả ký và không dấu.

Có các định nghĩa khác cho _fastcác loại được gọi là đảm bảo ít nhất là kích thước yêu cầu, nhưng sẽ tạo ra mã nhanh nhất dựa trên nền tảng, ví dụ bộ xử lý 32 bit có xu hướng thực hiện các hoạt động trên các số 32 bit hiệu quả hơn so với số 8 bit, vì vậy uint_fast8_t trên nền tảng 32 bit sẽ là số nguyên 32 bit (ít nhất là 8 bit, nhưng xử lý nhanh hơn).

Lệnh sizeof()được thực hiện tại thời gian biên dịch và được chuyển đổi thành hằng số, nó không được bộ xử lý thực thi. avr-gccbiết nó lớn như thế nào đã định nghĩa một intas, vì vậy nó biết hằng số nào để thay thế sizeof()cuộc gọi bằng.


Tôi không nghĩ int được đánh máy như bất cứ điều gì. Tôi nghĩ trình biên dịch 'quyết định', quyết định được tích hợp vào trình biên dịch. Bạn có thể cung cấp một liên kết, hoặc bằng chứng?
xe cứu thương

2
Bạn có thể thêm uint_fast8_tuint_least8_tvào danh sách của mình - sử dụng những thứ này cùng với uint8_t(khi cần độ rộng cố định) cho phép bạn viết mã di động hơn nhiều.
David

avr-gcc dường như không nhận ra loại int8_t. Tui bỏ lỡ điều gì vậy?
Aelgawad

1
@BlackyDucky bạn cần phải #include <stdint.h>- Tôi đã đề cập đến điều đó, nhưng trình phân tích cú pháp văn bản đã xóa nó vì <> xung quanh nó, xin lỗi về điều đó, đã được sửa bây giờ.
Tom Carpenter

6

Các kích thước của int, short int, long int, vv được quyết định bởi những người viết trình biên dịch. Các quy tắc của C là short int<= int<= long int, nhưng để lại nhiều chỗ cho các nhà văn biên dịch.

Người viết trình biên dịch phân tích các khả năng của bộ xử lý và cố gắng đưa ra các lựa chọn hợp lý cho CPU đó. Họ thường đưa ra các cờ dòng lệnh để buộc một intkích thước cụ thể để giúp mã cổng dễ dàng hơn trên các bộ xử lý.

Các chuỗi mã khác nhau được trình biên dịch tạo ra để xử lý các kích thước khác nhau của int; CPU được điều khiển bởi mã và do đó thực hiện kích thước được xác định bởi đầu ra của trình biên dịch.

Atmega sử dụng kiến ​​trúc CPU của AVR. Nó chủ yếu xử lý 8 bit dữ liệu tại một thời điểm. Vì vậy, trình biên dịch phải tạo mã để thực hiện số học nhiều byte.

Các không gian địa chỉ cơ bản của hầu hết các ATmege là 16 bit, vì vậy rất thuận tiện để có số học có thể truy cập tất cả số đó. Do đó, theo mặc định, an intlà 16 bit. Trong 'ngày xưa' của x86 với bộ nhớ được phân đoạn, trong đó địa chỉ có thể là 16 bit hoặc 32 bit và trình biên dịch được hướng dẫn để tạo cde cho một 'mô hình' cụ thể, trình biên dịch thường tạo mã cho kích thước intcó thể giữ kích thước của con trỏ cho 'mô hình bộ nhớ' đó.

Nếu bạn sử dụng một trình biên dịch cho bộ vi xử lý tương tự, có khả năng tạo mã cho hai (hoặc nhiều hơn) kích cỡ khác nhau của int ( intchứ không phải short int, long intchỉ int), thì đó là chính xác những gì nó sẽ làm để đáp ứng với những lá cờ thích hợp (hoặc của pragma ).

Trình biên dịch 'biết' kích thước của intnó đang tạo mã, vì vậy a sizeof(int)sẽ được thay thế bằng giá trị chính xác, tại thời điểm biên dịch, bởi trình biên dịch.


5

Kích thước của các loại dữ liệu C tiêu chuẩn được xác định bởi việc thực hiện trình biên dịch. Theo tiêu chuẩn , một int phải có khả năng chứa các giá trị trong phạm vi từ -32767 đến 32767 (16 bit), nhưng có thể lớn hơn. Kích thước của một int thường là giá trị tự nhiên nhất cho CPU - kích thước từ hoặc kích thước của thanh ghi CPU.

Cách duy nhất để biết chắc chắn là tham khảo hướng dẫn sử dụng trình biên dịch của bạn hoặc viết mã kiểm tra. Bạn nên có một bản sao của hướng dẫn sử dụng cho trình biên dịch nhúng vì các chi tiết cụ thể về căn chỉnh và lưu trữ dữ liệu có nhiều khả năng quan trọng trong lập trình nhúng. Phần mở rộng trình biên dịch (như để hỗ trợ ngắt) cũng quan trọng hơn.

Nếu bạn có trình biên dịch tuân thủ C99, việc sử dụng các loại uintX_t được xác định trong sẽ dễ dàng hơn để có được kích thước bạn muốn.

Để tham khảo, đây là các kích thước tối thiểu cho các loại dữ liệu khác được lấy từ phần 5.2.4.2.1 của tiêu chuẩn C99. Lưu ý rằng số học bổ sung của hai là không bắt buộc, mặc dù tôi không biết bất kỳ máy bổ sung hoặc ký hiệu cường độ nào ở trên đỉnh đầu của tôi.

char (kích thước byte): sizeof (char) luôn bằng 1. Các ký tự đã ký phải giữ các giá trị trong phạm vi -127 đến 127. Các ký tự không dấu phải giữ các giá trị trong phạm vi 0 đến 255. Tiêu chuẩn cũng chỉ định số bit tối thiểu trong một char / byte, là 8.

viết tắt: -32767 đến 32767 cho chữ ký, 0 đến 65535 cho dấu không dấu. Tương đương với 16 bit.

int: Tương tự như ngắn.

dài: -2147483647 đến 2147483647 cho ký, 0 đến 4294967295 cho không dấu. Tương đương với 32 bit.

dài dài: -9223372036854775807 đến 9223372036854775807 để ký, 0 đến 18446744073709551615 cho không dấu. Tương đương với 64 bit.

con trỏ: Thực hiện xác định. Tiêu chuẩn cho phép "các yêu cầu đại diện và căn chỉnh" khác nhau cho các con trỏ tới các loại dữ liệu khác nhau, nhưng tôi chưa bao giờ thấy điều đó trong thực tế.

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.