2015-02-23 16 views
7

Hiểu biết của tôi về size_t là nó sẽ đủ lớn để giữ bất kỳ giá trị (số nguyên) nào mà bạn có thể mong đợi nó được yêu cầu giữ. Ví dụ, nếu bạn đang sử dụng một cái gì đó giống như vòng lặp for để lặp qua tất cả các phần tử trong một vector, thì size_t thường sẽ dài 64 bit (hoặc ít nhất là trên hệ thống của tôi) trong để nó có thể giữ tất cả các giá trị trả về có thể từ vector.size().C++: Có lý do nào để sử dụng uint64_t thay vì size_t

Hoặc ít nhất, tôi nghĩ điều đó là chính xác?

Vì vậy, là có lý do nào để sử dụng A hơn B:

A: for(uint64_t i = 0; i < v.size(); ++ i)

B: for(size_t i = 0; i < v.size(); ++ i)

Nếu tôi sai với lời giải thích của tôi hoặc bạn có một lời giải thích tốt hơn, xin vui lòng chỉnh sửa.

Chỉnh sửa: Tôi nên thêm rằng sự hiểu biết của tôi là size_t hoạt động như một số nguyên không dấu bình thường - có lẽ điều đó không đúng?

+0

nếu bạn cần đảm bảo rằng int của bạn sẽ là 64 bit vì bất kỳ lý do nào (thường là thao tác byte). 'size_t' có thể thay đổi tùy thuộc vào hệ thống của bạn và tùy chọn biên dịch –

+0

' size_t' không được bảo đảm là 64bit – dtech

+0

Nếu bạn sử dụng 'uint64_t' trên mục tiêu 32 bit, bạn có thể đạt được hiệu suất tối ưu. – sharptooth

Trả lời

3

Trường hợp chính xác sẽ là for(std::vector::size_type i ....

Với mục đích lặp thông qua một vector, hoặc một cái gì đó thuộc loại đó, bạn sẽ khó đẩy để tìm một trường hợp size_t là không đủ lớn, và uint64_t là,

Tất nhiên, trên 32 -bit máy, size_t thường sẽ là 32 bit, nhưng bạn có thể muốn đối phó với số lớn hơn 4 tỷ, mà sẽ đòi hỏi nhiều hơn 32 bit, và điều này chắc chắn là một trường hợp sử dụng cho uint64_t. Nói cách khác, uint64_t được đảm bảo là 64 bit, size_t không phải là 64 bit trong tất cả các máy/kiến ​​trúc.

8

size_t là kiểu trả về là sizeof.

Tiêu chuẩn cho biết đó là một typedef của một số loại số nguyên không dấu, và đủ lớn để giữ kích thước của bất kỳ đối tượng có thể nào.
Nhưng nó không ủy quyền cho dù đó là nhỏ hơn, lớn hơn, hoặc kích thước tương tự như uint64_t (một typedef cho một số nguyên không cố định 64-bit không cố định), cũng không phải trong trường hợp thứ hai cho dù đó là cùng loại.

Do đó, sử dụng size_t ở nơi có ngữ nghĩa chính xác.
Giống như đối với số size() của số std::vector<T> (std::vector nhận số size_type từ phân bổ đã sử dụng, std::allocator<T> sử dụng size_t).

+0

Không vi phạm, nhưng 'std :: vector :: size()' trả về 'std :: vector :: size_type' – Nick

+0

Có, và đến từ bộ cấp phát. – Deduplicator

5

uint64_t được đảm bảo là 64 bit. Nếu bạn cần 64 bit, bạn nên sử dụng nó

size_t không được bảo đảm là 64 bit, có thể là 128 bit trong một máy trong tương lai. Do đó, từ khóa uint_64 được dành riêng cho nó :)

+0

phải được "đảm bảo TO" là – dtech

2

std::size_t được định nghĩa là một loại số nguyên không dấu. Chiều dài của nó phụ thuộc vào nền tảng. v.size() sẽ luôn trả về giá trị loại std::size_t, do đó, tùy chọn B luôn chính xác.

2

Không, size_t hoàn toàn không có kết nối với "đang giữ bất kỳ giá trị số nguyên nào mà bạn có thể mong đợi nó được yêu cầu giữ". Bạn đã lấy cái này ở đâu vậy?

size_t được coi là đủ lớn để giữ kích thước byte của bất kỳ đối tượng liên tục nào trong quá trình triển khai đã cho. Về mặt khái niệm, điều này là ít hơn "bất kỳ giá trị số nguyên" nào. Ngôn ngữ không đảm bảo rằng bạn được phép tạo các đối tượng chiếm toàn bộ lưu trữ địa chỉ, có nghĩa là size_t là khái niệm thậm chí không đủ để giữ số byte địa chỉ bộ nhớ.

Nếu bạn muốn kết hợp "bất kỳ giá trị số nguyên nào" với kích thước bộ nhớ, thì loại thích hợp sẽ là uintptr_t, lớn hơn khái niệm size_t. Nhưng tôi không thấy bất kỳ lý do nào để buộc "bất kỳ giá trị nguyên" nào vào đặc điểm bộ nhớ. Ví dụ. mặc dù uintptr_t lớn hơn size_t, nhưng không đảm bảo đủ lớn để giữ kích thước của tệp lớn nhất trong hệ thống tệp của nền tảng của bạn.

Lý do bạn có thể sử dụng size_t để lặp qua các yếu tố của std::vector là véc tơ được nội bộ dựa trên một mảng. Mảng là các đối tượng liên tục, đó là lý do tại sao kích thước của chúng được bao phủ bởi size_t. Nhưng khi bạn xem xét một vùng chứa không liền kề, như std::list, size_t không còn được đảm bảo đủ để đo hoặc lập chỉ mục các vùng chứa đó nữa.

uint64_t có thể dễ dàng lớn hơn size_t. Nhưng nó là khá có thể là bạn có thể phải làm việc với các giá trị số nguyên không phù hợp với uint64_t.

+0

'std :: malloc' và' std :: allocator' cũng sử dụng 'std :: size_t'. – tmlen

+0

Ngay cả 'uintptr_t' có thể quá nhỏ. Vì không có giới hạn cho các giá trị trong mô tả OP ... – Deduplicator

+0

@tmlen: Chúng thực hiện vì chúng phân bổ * khối * bộ nhớ liên tục, tức là chúng phân bổ mảng byte. Đối với họ nó là hoàn toàn thích hợp để sử dụng 'size_t'. – AnT

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