2012-04-10 24 views
8

Trong điều sau đây:Hai trường hợp trong khi cố gắng để in NULL, một hoạt động, SegFaults khác

printf("Example%s\n",NULL); 
printf("%s\n",NULL); 

tôi nhận được kết quả như sau:

Example(null) 
Segmentation Fault 

Khi tôi đã cố gắng lùi trong GDB nó cho thấy printf() là được chuyển đổi thành puts(). Nhưng tôi dường như không hiểu tại sao điều này lại xảy ra.

BTW Tôi tìm thấy this bài viết nhưng dường như vẫn không có ý nghĩa.

+0

'gcc' không khác nhau tối ưu hóa như vậy. Xem phần 2.3 và 3.1 cụ thể là http://www.ciselant.de/projects/gcc_printf/gcc_printf.html – FatalError

+1

Ngoài ra, hãy xem báo cáo lỗi 'gcc' này để thảo luận thêm về lý do tại sao điều này không được coi là lỗi: http: //gcc.gnu. org/bugzilla/show_bug.cgi? id = 25609 – shf301

+0

Câu hỏi tương tự: [Không nhận được lỗi phân đoạn trong C] (http://stackoverflow.com/questions/8861833/not-getting-segmentation-fault-in-c) –

Trả lời

15

Tiêu chuẩn nói rằng đi qua một con trỏ NULL như là đối số đến một printf với %s specifier là hành vi undefined (ví dụ: bất cứ điều gì có thể xảy ra), vì vậy cả hai hành vi này là hợp pháp.

Trong trường hợp đầu tiên, thư viện chuẩn (cụ thể là mã printf) đang giúp bạn bằng cách in (null). Trong trường hợp thứ hai, thay vào đó, trình tối ưu hóa hiểu rằng printf của bạn có thể được thay thế bằng puts (hiệu quả hơn) mà không có bất kỳ thay đổi nào đối với "hành vi có thể quan sát" của chương trình và do đó thay thế nó. Tuy nhiên, puts không xảy ra chứa mã kiểm tra NULL của printf và do đó bạn nhận được lỗi phân đoạn.


  1. C99, §7.19.6.1, ¶8:

    đối số phải là một con trỏ tới phần tử đầu tiên của một mảng của kiểu nhân vật.

    ¶9:

    Nếu bất kỳ tranh luận không phải là loại chính xác cho các đặc điểm kỹ thuật chuyển đổi tương ứng, hành vi này là không xác định.

    Bạn rơi vào trường hợp cuối cùng này, bởi vì NULL không phải là "một con trỏ tới phần tử đầu tiên của một mảng của kiểu nhân vật.

+1

Chính xác; 'printf' thứ hai chỉ in đối số đã cho, theo sau là một dòng mới, chính xác là những gì' puts' làm; cái đầu tiên, thay vào đó, làm những thứ phức tạp hơn một chút. Nhưng dù sao, đây là những chi tiết cụ thể về việc triển khai thực hiện: điều quan trọng là bạn không được chuyển 'NULL' làm đối số cho' printf' bằng '% s', vì nó là hành vi không xác định. –

+0

Cảm ơn sự giúp đỡ của bạn :) – noMAD

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