2009-12-05 16 views
14

Một khách hàng gần đây đã thực hiện phân tích tĩnh của codebase C của nhà tuyển dụng của tôi và cho chúng tôi kết quả. Trong số các bản vá hữu ích là yêu cầu thay đổi macro do { ... } while(0) nổi tiếng thành do { ... } while(0,0). Tôi hiểu bản vá của họ đang làm gì (sử dụng toán tử chuỗi để trả lại để đánh giá giá trị của "0" thứ hai, vì vậy hiệu quả là như nhau) nhưng không rõ lý do tại sao họ ưu tiên biểu mẫu thứ hai trên biểu mẫu đầu tiên .Trong các macro C, người ta có thích {...} trong khi (0,0) trên do {...} trong khi (0) không?

Có lý do chính đáng nào tại sao người ta nên thích dạng macro thứ hai hoặc phân tích tĩnh của khách hàng của chúng ta quá phức tạp?

+5

Công cụ phân tích tĩnh của khách hàng của bạn đã quá đáng, điều đó chắc chắn. –

+7

Tôi muốn "quá dư thừa". –

+3

Tôi không thể nghĩ ra bất kỳ lý do nào để làm điều này. Có lẽ một số công cụ phàn nàn với một điều kiện (0) dọc theo dòng "điều này sẽ không bao giờ xảy ra" nhưng bất kỳ công cụ như vậy nên 1) nhận ra rằng đây là một thành ngữ rất phổ biến trong C với macro và 2) phân biệt giữa làm ... trong khi (0) và trong khi (0) {}. Bạn đã yêu cầu họ cho một lý do? –

Trả lời

11

Vâng, tôi sẽ đi cho một câu trả lời:

Có một lý do chính đáng tại sao người ta nên thích hình thức thứ hai của vĩ mô ...?

Không. Không có lý do chính đáng. Cả hai luôn luôn đánh giá sai, và bất kỳ trình biên dịch phong nha có lẽ sẽ lần lượt một thứ hai vào đầu tiên trong hội đồng nào. Nếu có bất kỳ lý do nào khiến nó không hợp lệ trong một số trường hợp, C đã đủ dài để lý do đó được nhiều người biết đến hơn I.

Nếu bạn thích mã làm đôi mắt của mình, hãy sử dụng while(0,0). Nếu không, hãy sử dụng phần còn lại của thế giới lập trình C và sử dụng công cụ phân tích tĩnh của khách hàng của bạn để đẩy nó.

+0

Nó không đánh giá bất cứ điều gì; và do-loop không phải là một biểu thức và không có giá trị. Hãy thử gán nó int x = macro(); và nó không biên dịch được. – Clifford

+1

Tôi đề cập đến việc đánh giá '0' so với' 0,0', không phải là vòng lặp 'do {} trong khi (0)' nói chung. –

+0

Ok; Tôi vẫn đang cố gắng tìm hiểu toàn bộ lợi ích. – Clifford

11

Chỉ cần một đoán là tại sao họ có thể đề nghị sử dụng

do { ... } while(0,0) 

qua

do { ... } while(0) 

Mặc dù không có sự khác biệt về hành vi và nên có sự khác biệt chi phí thời gian chạy giữa hai người.

Tôi đoán là công cụ phân tích tĩnh than phiền về vòng lặp while bị kiểm soát bởi hằng số trong trường hợp đơn giản và không sử dụng khi sử dụng 0,0. Đề xuất của khách hàng có lẽ chỉ là để họ không nhận được một loạt các mặt tích cực sai từ công cụ này. Ví dụ tôi thỉnh thoảng gặp các tình huống mà tôi muốn có một câu lệnh điều kiện được kiểm soát bởi một hằng số, nhưng trình biên dịch sẽ phàn nàn với một cảnh báo về một biểu thức có điều kiện đánh giá đến một hằng số. Sau đó, tôi phải nhảy qua một số hoops để có được trình biên dịch ngừng phàn nàn (vì tôi không muốn có cảnh báo giả).

Đề xuất của khách hàng là một trong những hoops mà tôi đã sử dụng để làm yên lặng cảnh báo đó, mặc dù trong trường hợp của tôi nó không kiểm soát vòng lặp while, nó phải đối phó với xác nhận "luôn thất bại". Thỉnh thoảng, tôi sẽ có một khu vực mã mà không bao giờ nên thực thi (có thể là trường hợp mặc định của một switch). Trong tình huống đó, tôi có thể có một xác nhận luôn thất bại với một số thông báo:

assert(!"We should have never gotten here, dammit..."); 

Nhưng, ít nhất một trình biên dịch tôi sử dụng cảnh báo về biểu thức luôn luôn đánh giá sai. Tuy nhiên, nếu tôi thay đổi thành:

assert(("We should have never gotten here, dammit...", 0)); 

Cảnh báo biến mất và mọi người đều hạnh phúc. Tôi đoán rằng ngay cả công cụ phân tích tĩnh của khách hàng cũng sẽ như vậy.Lưu ý rằng tôi thường giấu rằng chút hoop nhảy đằng sau một vĩ mô như:

#define ASSERT_FAIL(x) assert(((x), 0)) 

Nó có thể là tốt đẹp để có thể cho biết các nhà cung cấp công cụ để sửa chữa vấn đề, nhưng có thể có trường hợp chính đáng mà họ thực sự muốn để chẩn đoán một vòng lặp được kiểm soát bởi một biểu thức boolean không đổi. Không phải đề cập đến thực tế là ngay cả khi bạn thuyết phục một nhà cung cấp công cụ để thực hiện một thay đổi như vậy, điều đó không giúp bạn trong năm tới hoặc lâu hơn mà nó có thể làm để thực sự có được một sửa chữa.

+2

+1 Đây có thể là nó, nhưng nếu đây là trường hợp các cảnh báo này chỉ nên được vô hiệu hóa với các tùy chọn dòng lệnh. Tại sao nhảy qua hoops khi bạn chỉ có thể tắt các hoops mà không cần thiết? –

+1

Vâng, đối với một, futzing xung quanh với trình biên dịch hoặc các tùy chọn công cụ có thể được coi là một hình thức nhảy hoop. Screwing xung quanh với các makefiles hoặc bất cứ điều khiển xây dựng của bạn thường là nhiều hơn nữa ma thuật đen hơn C tiền xử lý hackery là (và đó là nói rất nhiều). Đối với người khác, bạn có thể không muốn cảnh báo bị vô hiệu hóa cho mọi thứ - có thể chỉ dành cho các macro gỡ lỗi dường như cần các thủ thuật ngu ngốc này. –

+0

+1 Đây phải là câu trả lời được chấp nhận. – Calmarius

8

Sử dụng khi (0,0) ngăn trình biên dịch Microsoft tạo cảnh báo về điều kiện là hằng số (Cảnh báo C4127).

Khi cảnh báo này được bật (ví dụ: với/W4 hoặc/Wall), có thể tắt theo từng trường hợp với mẹo nhỏ đẹp này (see this other thread).

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