2013-08-24 18 views
6

Về cơ bản tôi đang yêu cầu cho một dịch:Những khía cạnh nào của sự dịch chuyển trái đã ký không được xác định với GCC?

GCC không sử dụng các vĩ độ được đưa ra trong C99 chỉ để điều trị một số khía cạnh của ký '< <' như không xác định, nhưng điều này có thể thay đổi.

(GCC 4.8.1 manual, paragraph 4.5)

gì 'vĩ độ' được đưa ra? Những khía cạnh nào đó?

+0

Câu hỏi hay! Câu đó sẽ đạt được giải nhất cho fogginess! Tôi không phải là người nói tiếng Anh bản địa, vì vậy tôi không thể chắc chắn 100%, nhưng kỹ năng tiếng Anh của tôi khá tiên tiến và tôi vẫn còn bối rối bởi từ "chỉ". Tôi không thể quyết định những thuật ngữ khác nó đề cập đến. * Chỉ * C99 sử dụng vĩ độ? * Chỉ * một số khía cạnh nhất định được xử lý bằng vĩ độ. GCC không sử dụng vĩ độ * chỉ * cho ký hiệu '<<'? Điều này dường như là giải thích tốt nhất, nhưng sau đó "những khía cạnh nhất định": nguyên nhân UB có thể chỉ là một cặp vợ chồng, nó sẽ đơn giản hơn nhiều để nói những gì GCC hiện đang làm và cảnh báo về những thay đổi trong tương lai! –

Trả lời

2

Câu trả lời khác đã chỉ ra các khía cạnh của << là hành vi không xác định. Tôi đoán là bạn muốn có một "bản dịch" của gcc sang ngôn ngữ chung.

Nếu một hành vi không được xác định bởi tiêu chuẩn C, người triển khai trình biên dịch có thể lấy "vĩ độ" để làm bất cứ điều gì phù hợp với họ nếu trường hợp như vậy xảy ra. Đặc biệt, họ không phải thực hiện một chẩn đoán hoặc phát hiện trường hợp đó, và có thể giả vờ rằng nó không bao giờ xảy ra. Đó là trách nhiệm của lập trình viên để viết chương trình của mình sao cho hành vi của nó luôn được xác định.

Trong trường hợp dịch trái, điều này có nghĩa là một trình biên dịch sẽ không phải kiểm tra tràn và có thể giả vờ rằng một vòng lặp như

for (int i = 1; i > 0; i <<= a) { 
.... change a in some complicated way ... 
} 

sẽ không bao giờ chấm dứt.

Câu mà bạn đang trích dẫn cho biết rằng họ không làm một điều như vậy, tuy nhiên, nhưng các phiên bản gcc trong tương lai có thể làm như vậy.

2

C99 §6.5.7/3-4 liệt kê hai hành vi không xác định cụ thể liên quan đến các nhà điều hành dịch trái (<<):

3) [...] Nếu giá trị của toán hạng bên phải là tiêu cực hay lớn hơn hoặc bằng với chiều rộng của toán hạng bên trái được quảng bá, hành vi là không xác định.

4) Kết quả của E1 << E2 là [...]. Nếu E1 có loại có ký hiệu và giá trị không âm, và E1 × 2 E2 là thể hiện trong loại kết quả, thì đó là giá trị kết quả; nếu không, hành vi là không xác định.

Làm thế nào chính xác GCC hoạt động trong những trường hợp này, tôi không thể nói. Đó là hoàn toàn chào đón để cung cấp cho hành vi được xác định trong những tình huống này; tuy nhiên, mã như vậy sẽ vẫn không được xác định khi được biên dịch với các trình biên dịch khác.

My đoán là xử lý GCC đã ký trái chuyển hệt unsigned trái chuyển-có nghĩa là, nếu tính x << y như (signed)((unsigned)x << y) bằng cách làm thay đổi chút (có khả năng loại bỏ bất kỳ bit cao), và sau đó reinterpreting kết quả như một ký số lượng. Điều này có ngụ ý rằng bit giá trị quan trọng nhất của một số nguyên đã ký được chuyển vào bit dấu; có vẻ hơi kỳ lạ so với phối cảnh số học nhưng lại có ý nghĩa hoàn hảo từ góc độ bitwise.

3

Thông tin về toán tử dịch chuyển trái trong tiêu chuẩn dự thảo C99 (ISO/IEC9899: TC3, còn gọi là WG14/N1256) khá ít.

Mục 6.5.7 (toán tử dịch chuyển bit) đã được trích dẫn bởi Alter Mann.

Phụ lục J, phần k.2 (hành vi Không xác định) cho biết như sau:

Các hành vi là undefined trong các trường hợp sau đây:
[...]

- Một biểu thức được chuyển theo số âm hoặc số tiền lớn hơn hoặc bằng với chiều rộng của biểu thức được quảng cáo (6.5.7).

- Biểu thức có loại được quảng cáo đã ký được dịch chuyển trái và giá trị của biểu thức là âm hoặc kết quả chuyển dịch sẽ không thể thể hiện được trong loại quảng cáo (6.5.7).

Tôi không nghĩ rằng nó được phép triển khai phù hợp để thực hiện một số hành vi bắt buộc chưa xác định được xác định.Nếu tôi không hiểu nhầm việc triển khai được phép xác định hành vi không xác định (nhưng không bắt buộc phải) và được yêu cầu chỉ định hành vi được xác định thực hiện, nhưng hành vi không xác định không được là được chỉ định. Điều này không có nghĩa là triển khai không thể chọn một hành vi có ý nghĩa lành mạnh lành mạnh nhưng không thể cho phép người dùng dựa vào điều đó (nó không thể "chỉ định").

Tôi thừa nhận tôi không hoàn toàn chắc chắn về điều đó. Hi vọng điêu nay co ich.

Edit: Sau khi phản ánh hơn nữa tôi nghĩ rằng việc thực hiện phù hợp có thể chỉ định một hành vi cho những gì tiêu chuẩn xét thấy hành vi undefined , nhưng chương trình kết quả không thể được gọi phù hợp (xem phần 3.4.3).

+1

Ví dụ về hành vi không xác định luôn được dự định là (và thường được định nghĩa) bởi các trình biên dịch, một chuỗi '%' không xác định trong một chuỗi định dạng 'printf()' là hành vi không xác định. –

+0

Vì vậy, nếu thực hiện xác định một hành vi được xác định, nơi nó được yêu cầu để xác định hành vi không xác định, thực hiện đó là trưng bày hành vi không xác định? Kafkaesque ... –

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