2016-08-24 13 views
6

Tôi biết rằng các tiêu chuẩn C cho phép triển khai nơiBất động thực hiện nơi sizeof (size_t) <sizeof (unsigned int)

(sizeof(unsigned) > sizeof(size_t)) 

hoặc

(sizeof(int) > sizeof(ptrdiff_t)) 

là đúng. Nhưng có bất kỳ triển khai thực sự nào trong đó một trong những điều này là đúng không?

nền

Tôi đã viết một chức năng tương tự như asprintf() (kể từ asprintf() không phải là xách tay), và snprintf() trả về một int nhưng cần một đối số size_t, vì vậy tôi nên kiểm tra nếu leni (hình dưới đây) không phải là ít hơn SIZE_MAX trong mã này?

va_copy(atmp,args) 
int leni = vsnprintf(NULL,0,format,atmp); //get the size of the new string 
va_end(atmp); 
if(leni<0) 
    //do some error handling 
if(leni>=SIZE_MAX) //do i need this part? 
    //error handling 
size_t lens = ((size_t)leni)+1; 
char *newString = malloc(lens); 
if(!newString) 
    //do some error hanling 
vsnprintf(newString,lens,format,args)!=lens-1) 
+0

Tôi không chắc chắn điều đó thực sự có thể xảy ra, nếu không 'sizeof (char [LARGE_NUMBER])' sẽ không hoạt động. –

+0

@OliverCharlesworth Nó không allways làm việc, nếu bạn viết một cái gì đó như char str [1024ULL * 1024ULL * 1024ULL * 5] ;, bạn sẽ nhận được một lỗi biên dịch trên máy 32bit (ít nhất là trong trường hợp của tôi với gcc -m32) (nhưng không trên AMD64) – 12431234123412341234123

+0

@OliverCharlesworth Nó không phải. Nếu biểu thức hằng số trong dấu ngoặc đơn làm cho một đối tượng không thể được biểu diễn bởi size_t, đó sẽ là kết quả của sizeof, thì trình biên dịch sẽ tạo ra một lỗi. – 2501

Trả lời

3

Mặc dù tiêu chuẩn không cấm INT_MAX sẽ không nhỏ hơn SIZE_MAX, hàm vsnprintf đảm bảo rằng giá trị trả lại sẽ không lớn hơn SIZE_MAX.

Nếu các hàm thành công, thì giá trị trả về phải nhỏ hơn đối số thứ hai . Đối số này có loại size_t, do đó giá trị trả về phải nhỏ hơn SIZE_MAX. .

Và nếu bạn không bị thuyết phục, bạn luôn có thể sử dụng chỉ thị tiền xử lý đánh giá INT_MAX> SIZE_MAX và sau đó bao gồm mã cần thiết để kiểm tra kết quả của vsnprintf.


Từ định n được đề cập trong trích dẫn tiêu chuẩn dưới đây, là đối số thứ hai để vsnprintf.

(Trích dẫn từ: ISO/IEC 9899: 201x 7.21.6.12 Chức năng vsnprintf 3)
Chức năng vsnprintf trả về số ký tự mà có thể đã được viết đã n được đủ lớn, không đếm chấm dứt ký tự null hoặc giá trị ative phủ định nếu xảy ra lỗi mã hóa. Do đó, đầu ra null kết thúc đã được ghi là hoàn toàn nếu và chỉ khi giá trị trả về là không âm và nhỏ hơn n.

+0

Xin lỗi nếu tôi không hiểu bạn 100%. Nhưng nếu bạn đặt n thành 0, (những gì tôi làm) Số trả lại không được bằng hoặc nhỏ hơn n, vì vậy có thể không phải là giá trị trả lại lớn hơn SIZE_MAX không? – 12431234123412341234123

+0

@ 12431234123412341234123 Chuẩn ngụ ý rằng giá trị trả về không được lớn hơn n, có giới hạn SIZE_MAX. Nếu bạn nghĩ rằng phán quyết quá mơ hồ để đáng tin cậy, chỉ cần thêm kiểm tra được bảo vệ bởi các chỉ thị tiền xử lý và quên nó đi. – 2501

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