2015-10-12 31 views
8
char s1[] = "0"; 
char s2[] = "9"; 
printf("%d\n", strcmp(s1, s2)); // Prints -9 
printf("%d\n", strcmp("0", "9")); // Prints -1 

Tại sao strcmp trả về các giá trị khác nhau khi nhận được cùng các tham số?strcmp() trả lại các giá trị khác nhau cho cùng một chuỗi so sánh

Giá trị đó vẫn hợp pháp vì trang của strcmp cho biết giá trị trả về của strcmp có thể nhỏ hơn hoặc lớn hơn 0, nhưng tôi không hiểu tại sao chúng khác nhau trong ví dụ này.

+2

http://ideone.com/S3dYMQ nếu có ai muốn chơi ... –

Trả lời

4

Tôi giả sử bạn đang sử dụng GCC khi biên dịch, tôi đã thử trên 4.8.4. Bí quyết ở đây là GCC hiểu ngữ nghĩa của các chức năng thư viện chuẩn nào đó (strcmp là một trong số chúng). Trong trường hợp của bạn, trình biên dịch sẽ loại bỏ hoàn toàn cuộc gọi thứ hai strcmp, vì nó biết rằng kết quả của strcmp hằng số chuỗi đã cho "0""9" sẽ là âm và giá trị tương thích chuẩn (-1) sẽ được sử dụng thay vì thực hiện cuộc gọi. Nó không thể thực hiện tương tự với cuộc gọi đầu tiên, bởi vì s1s2 có thể đã bị thay đổi trong bộ nhớ (hãy tưởng tượng một ngắt hoặc nhiều luồng, v.v.).

Bạn có thể thực hiện thử nghiệm để xác thực điều này. Thêm const vòng loại để các mảng để cho GCC biết rằng họ không thể thay đổi:

const char s1[] = "0"; 
const char s2[] = "9"; 
printf("%d\n", strcmp(s1, s2)); // Now this will print -1 as well 
printf("%d\n", strcmp("0", "9")); // Prints -1 

Bạn cũng có thể nhìn vào sản lượng lắp ráp thành các trình biên dịch (sử dụng -S cờ).

Cách tốt nhất để kiểm tra là sử dụng -fno-builtin, điều này sẽ vô hiệu hóa tối ưu hóa này. Với tùy chọn này, mã ban đầu của bạn sẽ in -9 trong cả hai trường hợp

3

Sự khác biệt là do việc triển khai strcmp. Miễn là nó phù hợp với (< 0, 0,> 0), nó không quan trọng đối với nhà phát triển. Bạn không thể dựa vào bất cứ điều gì khác. Đối với tất cả các bạn biết, mã nguồn có thể được xác định nó phải là tiêu cực, và ngẫu nhiên tạo ra một số âm để ném bạn đi.

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