2014-12-04 18 views
6

Đặc biệt, tôi đã nhận sau mã trong giao diện thư viện:Có thêm điều tra viên vào enum break ABI không?

typedef enum 
{ 
    state1, 
    state2, 
    state3, 
    state4, 
    state5, 
    state_error = -1, 
} State; 

tôi nghiêm cấm để phá vỡ ABI. Tuy nhiên, tôi muốn thêm state6 và state7. Nó sẽ phá vỡ ABI?

Tôi tìm thấy here một số mẹo, nhưng tôi hơi nghi ngờ nếu đó là trường hợp của tôi?

Bạn có thể ...

  • thêm điều tra viên mới cho một enum hiện có.

Ngoại lệ: nếu điều đó dẫn đến trình biên dịch chọn loại cơ bản lớn hơn cho enum, điều đó làm cho sự thay đổi không tương thích nhị phân. Thật không may, các trình biên dịch có một số mất thời gian để chọn kiểu cơ bản, do đó, từ quan điểm thiết kế API, bạn nên thêm một số tử Max .... với giá trị lớn rõ ràng (= 255, = 1 < < 15, v.v.) để tạo khoảng thời gian của các giá trị số đếm được đảm bảo để phù hợp với loại cơ bản được chọn, bất cứ điều gì có thể được.

+2

'state3' có ba mã khác nhau? – Deduplicator

+1

Thêm một enum mới trong khi để lại những cái hiện có một mình không nên phá vỡ khả năng tương thích ABI miễn là kích thước của loại cơ bản không thay đổi như là kết quả của việc bổ sung. Đó là những gì tài liệu được trích dẫn của bạn nói. –

Trả lời

10

Câu hỏi của bạn là một ví dụ điển hình tại sao việc duy trì lâu dài khả năng tương thích ABI là một nhiệm vụ khó khăn. Cốt lõi của vấn đề ở đây là khả năng tương thích phụ thuộc không chỉ vào loại đã cho, mà còn phụ thuộc vào cách nó được sử dụng trong các nguyên mẫu hàm/phương thức hoặc các kiểu phức tạp (ví dụ: cấu trúc, công đoàn, vv).

(1) Nếu điều tra được sử dụng ở bất kỳ nơi nào làm đầu ra từ thư viện (ví dụ: trả về giá trị hoặc hàm điền địa chỉ được cung cấp bởi tham số đầu ra a.k.a), thay đổi sẽ phá vỡ ABI. Hãy xem xét việc liệt kê là một hợp đồng nói rằng "ứng dụng không bao giờ thấy các giá trị khác sau đó được liệt kê". Việc thêm thành viên enum mới sẽ phá vỡ hợp đồng này vì các ứng dụng cũ hiện có thể thấy các giá trị mà chúng chưa bao giờ tính đến.

(2) Nếu điều tra được sử dụng đúng như đầu vào vào thư viện (ví dụ như tham số của hàm chỉ thay đổi hành vi của hàm/thư viện), thì nó sẽ giữ khả năng tương thích: Bạn đã thay đổi hợp đồng trong cách mà không bao giờ có thể làm tổn thương khách hàng tức là ứng dụng gọi điện. Các ứng dụng cũ sẽ không bao giờ sử dụng giá trị mới và sẽ có hành vi cũ, các ứng dụng mới chỉ nhận được nhiều tùy chọn hơn.

+0

Đặt một cách khác, người ta có thể làm suy yếu các yêu cầu của thư viện mà không gây hại, nhưng người ta có thể không làm suy yếu sự bảo đảm của nó. Cẩn thận với những người dựa vào tham số-xác nhận để từ chối đầu vào không hợp lệ theo một cách cụ thể mặc dù. Những tồn tại ... – Deduplicator

3

Báo giá thực sự là trường hợp của bạn. Đơn giản thêm các giá trị enum mới vào cuối (nhưng trước state_error vì nó có giá trị khác) và nó phải tương thích nhị phân, trừ khi, như được đề cập trong báo giá bạn cung cấp, trình biên dịch chọn sử dụng loại có kích thước khác dường như không có khả năng trong trường hợp của một enum nhỏ như vậy.

Cách tốt nhất là thử và kiểm tra: một đơn giản sizeof(State) được thực hiện trước và sau khi thay đổi là đủ (mặc dù bạn cũng có thể muốn kiểm tra xem các giá trị có giữ nguyên không).

2

Hãy xem ở mức cao nhất có giá trị Enumerator-id: state3 là 2.

Điều đó có nghĩa, ngay cả khi trình biên dịch nên đã chọn char như các loại cơ bản, bạn có thể thoải mái phù hợp với 100 thêm Enumerator-id ở đó, mà không có rủi ro thiệt hại cho khả năng tương thích nhị phân.

Điều đó giả định trước rằng người dùng cung cấp giá trị của trình lặp, thay vì bao giờ hãy đọc một.

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