Chính xác thì “Objective-C là một tập hợp siêu của C hơn C ++” có nghĩa là gì?


87

Từ những gì tôi đọc ở đó: Tại sao Objective-C lại không phổ biến bên ngoài cộng đồng Apple?

Objective-C là một tập hợp siêu của C (thực tế là nghiêm ngặt hơn nhiều so với C ++) nên vấn đề tương thích ngược không phát sinh. Bất cứ điều gì bạn có thể làm trong C bạn có thể làm trong Objective-C.

Là một superset là nhị phân, giống như mang thai. Obj-C là một tập siêu của C, còn C ++ thì không.

Họ có nghĩa là gì bởi superset? Theo cách nào thì mục tiêu-C sẽ gần // tương thích ngược hơn với C? Mục tiêu-C tuân theo triết lý C chặt chẽ hơn C ++ ở điểm nào?

Có thể biên dịch bất kỳ chương trình C nào mà không cần sửa đổi bằng trình biên dịch C mục tiêu (tương thích 100%) không?

Đây là một câu hỏi về thiết kế và khả năng tương thích của ngôn ngữ lập trình hơn là một cuộc chiến về việc cái nào tốt hơn.

Câu trả lời:


134

Tôi đã chuẩn bị một sơ đồ đơn giản; nó không đẹp lắm, nhưng hy vọng sẽ hiểu được điểm trên:

  • Màu đỏ: tập hợp tất cả các chương trình hợp lệ trong C, C ++ và Objective-C (tương đối nhỏ)
  • Màu xanh lá cây: tập hợp tất cả các chương trình hợp lệ trong C và Objective-C, nhưng không hợp lệ trong C ++ (thậm chí nhỏ hơn)
  • Màu xám: tập hợp tất cả các chương trình hợp lệ trong Objective C và C ++, nhưng không hợp lệ trong C (trống, theo tôi biết)
  • Màu xanh lam: tập hợp tất cả các chương trình chỉ hợp lệ trong Mục tiêu C (tương đối lớn)
  • Màu vàng: tập hợp tất cả các chương trình chỉ hợp lệ trong C ++ (lớn nhất)

Tập hợp các chương trình C hợp lệ (màu đỏ và xanh lục) là một tập hợp con nghiêm ngặt của tập hợp các chương trình Mục tiêu C hợp lệ (màu xanh lam)

nhập mô tả hình ảnh ở đây


14
Còn về mục tiêu c ++ thì sao?
dùng1115057.


19
Bằng thước đo nào mà bạn khẳng định màu vàng "lớn hơn" màu xanh lam ở đây? Trực giác cho tôi biết rằng cả hai tập hợp sẽ là vô hạn.
wim

4
@wim: Và cả hai đều được biểu diễn dưới dạng tập con không đếm được của R ^ 2;) Đây là mẹo giống như bạn sẽ thấy N bên trong Q mặc dù chúng có cùng kích thước (và N là tập con nghiêm ngặt của Q).
Maciej Piechotka

3
Tôi đã suy nghĩ về nó thêm một chút nữa và nhận ra rằng tập ObjC ++ sẽ không thực sự bao quanh tất cả những điều này. Nó là một tập siêu của C ++, nhưng không phải là một tập siêu nghiêm ngặt của ObjC. Các chương trình tương tự là C hợp pháp, nhưng C ++ bất hợp pháp (vùng màu xanh lá cây) là objC ++ bất hợp pháp.
Rob Napier

62
  1. Họ có nghĩa là gì bởi superset?

    Họ có nghĩa là superset nghiêm ngặt. Bất kỳ chương trình C hợp lệ nào sẽ được biên dịch bằng trình biên dịch Objective-C. Một số chương trình C hợp lệ sẽ không biên dịch bằng trình biên dịch C ++.

  2. Theo cách nào thì mục tiêu-C sẽ gần // tương thích ngược hơn với C?

    Đây là một ví dụ đơn giản:

    int *foo = malloc(12);
    

    Biên dịch trong C và Objective-C, nhưng không phải trong C ++. Tất nhiên, có những ví dụ khác.

  3. Mục tiêu-C tuân theo triết lý C chặt chẽ hơn C ++ ở điểm nào?

    Tất cả - Objective-C là một tập hợp siêu nghiêm ngặt của C.

  4. Có thể biên dịch bất kỳ chương trình C nào mà không cần sửa đổi bằng trình biên dịch C mục tiêu (tương thích 100%) không?

    Đúng.


2
Vâng, điều đó sẽ ổn. Có thể cho rằng bạn không cần Objective-C cho GUI, nếu bạn sẵn sàng tìm ra các hàm thời gian chạy cấp thấp để sử dụng.
Carl Norum

3
Chủ yếu là triết học.
Carl Norum

2
+1 Lời giải thích tuyệt vời. Tôi đề nghị rằng câu hỏi về "triết lý C" hơi mơ hồ, nhưng hầu hết các nhà quan sát có lẽ sẽ đồng ý rằng "mục tiêu" của C và "mục tiêu" của ObjC khác nhau. Mục đích của C là rất gần gũi với phần cứng, đồng thời cung cấp một số tóm tắt hữu ích về tính di động, trong khi mục tiêu của ObjC là mang lại phương pháp tiếp cận SmallTalk cho C. Vì Cacao đã trở thành một phần không thể thiếu của ObjC trong những năm gần đây, sự khác biệt này thậm chí còn mạnh mẽ hơn. "Triết lý" (cách tiếp cận thiết kế) của C-array và NSArray chắc chắn rất khác nhau.
Rob Napier

2
Điều đó hoàn toàn phụ thuộc vào chương trình. Có lẽ bạn sẽ không làm quá nhiều thứ kiểu C trong một chương trình Objective-C. Tại sao bạn lại sử dụng Objective-C?
Carl Norum

1
@ user1115057: bạn không nên lo lắng quá về cách mọi thứ được xem xét. Có hai vấn đề khi viết mã C ++ biên dịch dưới dạng (hoặc ít nhất là trông giống như) C. Một là bạn không nhận được bất kỳ lợi ích nào của C ++, nhưng đó là lời kêu gọi của bạn. Điều quan trọng là bạn đang viết bằng một phương ngữ bị hỏng của C không thực sự là C. Thay vào đó, bạn nên biên dịch mã C của mình bằng trình biên dịch C và liên kết nó với mã C ++ của bạn. Đó là mối quan tâm thứ hai không áp dụng với Objective-C, kể từ khi tập hợp con của Objective-C biên dịch như C, C.
Steve Jessop

31

Ngay từ đầu, C ++ đã được thiết kế như một "C tốt hơn", sửa chữa các thiếu sót trong thiết kế, cả thực tế và nhận thức, như các tác giả của C ++ đã trải qua ngôn ngữ này. Kết quả của quyết định thiết kế này Xlà một chương trình C hợp lệ không đảm bảo rằng nó Xsẽ biên dịch, chưa nói đến việc chạy, khi được xử lý bởi trình biên dịch C ++. Những thay đổi liên quan đến các cấu trúc cơ bản như ký tự chuỗi (chúng đã trở thành const char*), phép gán voidcon trỏ, chuyển đổi giữa enums và kiểu tích phân, ngữ nghĩa của toán tử gán ghép , v.v.

Hơn nữa, khi C99 xuất hiện, các tính năng đưa nó vào tiêu chuẩn C cập nhật đã bị loại khỏi tiêu chuẩn C ++ cập nhật. Một lần nữa, các tính năng ngôn ngữ rất quan trọng đã bị loại bỏ - đáng chú ý nhất là các bộ khởi tạo được chỉ định và các mảng có kích thước thay đổi.

Ngược lại, Objective C đã được định vị như một tập thay thế của C, yêu cầu tất cả các chương trình C hợp lệ phải có thể biên dịch được bằng trình biên dịch Objective C.


4
Tôi đã trả lời câu hỏi này vì tôi biết "superset" là gì, nhưng tôi không biết gì về Objective-C. Tôi đã thấy một tuyên bố trong một câu hỏi SO khác, rằng đoạn mã C hợp lệ int nil = 0; nil++;không biên dịch thành Objective-C. Vấn đề ở đó là gì, có phải điều hiển nhiên là Objective-C tạo ra các tiêu đề có sẵn, một khi được đưa vào, có thể phá vỡ mã của bạn chính xác như các tiêu đề C có thể không? Và do đó, tác giả của đoạn mã đó không nên đưa chúng vào.
Steve Jessop

2
"nil" thực sự là một #define hơn là một từ khóa. Bạn đang gặp sự cố vì objc / objc.h được bao gồm. Điều này tương tự với các vấn đề bạn gặp phải nếu bạn cố tạo một biến có tên là CÓ. (Xcode nêu bật những như thể họ thực sự từ khóa bởi vì nó dễ dàng hơn để suy nghĩ về nó theo cách đó, nhưng họ đang thực hiện dưới dạng mã C đơn giản.)
Rob Napier

4
BTW, thật đáng để thử xem objc. Rất ít nếu bạn quan tâm đến cách objC tồn tại trên đầu C. Những thứ mà bạn nghĩ sẽ là từ khóa (id, BOOL, Class, nil, v.v.) chỉ là các kiểu, cấu trúc đơn giản và xác định. Bạn thậm chí có thể triển khai thông điệp truyền qua tay trong pure-C. Đừng bao giờ làm điều đó. : D Nhưng bạn có thể. github.com/iosptl/ios6ptl/blob/master/ch28/Runtime/MyMsgSend.c
Rob Napier

2
@DanNeely: Rob Napier đã nói "không bao giờ, đừng bao giờ làm điều đó" như một bình luận về tệp được liên kết. Tệp được liên kết không phải là thời gian chạy Objective-C, nó chỉ là một bản hack nhanh cho thấy một số cách nhắn tin thực sự hoạt động.
Dietrich Epp

1
Tệp được liên kết không chứng minh việc truyền thông báo objC phức tạp như thế nào. Nó chứng tỏ rằng thời gian chạy có sẵn từ C và về nguyên tắc, bạn có thể chuyển đổi mã ObjC thành mã C. NHƯNG… điều này chậm nhất có thể. Nó dựa vào việc tôi biết kiểu trả về của các phương thức (và đối với một số kiểu trả về, tôi có thể cần biết kiểu bộ xử lý) và tôi đã cẩn thận chọn các phương thức không sử dụng tham số. Giải pháp đầy đủ có nhiều thủ thuật tinh vi (các bộ phận phải nằm trong trình lắp ráp vì chúng ăn gian với các khung ngăn xếp). Bạn đừng bao giờ cố gắng xây dựng lại nó.
Rob Napier

12

"Objective-C là một tập hợp con của C" có nghĩa là mọi chương trình C hợp lệ đều là một chương trình Objective-C hợp lệ (với cùng một ý nghĩa).

Người ta đôi khi nói, mặc dù không bằng C ++ chuyên gia, đó là C ++ là một superset của C. Điều này là không chính xác, đó là lý do trích dẫn của bạn được thực hiện một vấn đề lớn của việc so sánh hai.


9

Objective C là một tập hợp các phần mở rộng tương thích ngược với C. Điều này có thể thực hiện được vì các tính năng của Objective C được phân định theo hai cách rất đơn giản:

  • sử dụng ký tự @. Ký tự này hiện không được sử dụng trong ngôn ngữ C.
  • một phần mở rộng cú pháp đơn giản để gọi các phương thức [obj method:argument],. Trong C, dấu ngoặc vuông được sử dụng theo một cách rất cụ thể để lập chỉ mục mảng, và vì vậy đây là cú pháp C không hợp lệ. Các tiện ích mở rộng xây dựng trên cú pháp không hợp lệ sẽ không thay đổi ý nghĩa của bất kỳ thứ gì hợp lệ trong ngôn ngữ máy chủ.

Vì vậy, dễ dàng nhận thấy rằng không có chương trình nào sử dụng phần mở rộng Mục tiêu C có thể là một chương trình ISO C tuân thủ nghiêm ngặt, cho dù đơn giản đến đâu. Hơn nữa, theo định nghĩa, mọi chương trình ISO C đều có thể được khai báo là một chương trình Objective C hợp lệ. Objective C có thể dễ dàng theo dõi sự phát triển như C99 và C11.

Mặt khác, C ++ không chỉ đơn giản là phần mở rộng của C; nó là một ngôn ngữ khác thay đổi ý nghĩa của một số cú pháp của C. C ++ và C được duy trì riêng biệt, và do đó mối quan hệ của chúng thay đổi theo thời gian. Ví dụ: C đã có được các tính năng mới hoàn toàn không có trong C ++ và rất có thể sẽ không có trong C ++, chẳng hạn như mảng độ dài thay đổi C99. C ++ không thể dễ dàng chọn các tính năng C mới.

Nếu bạn viết một chương trình C di động, nó phải đồng thời là một chương trình C Objective. Nhưng sẽ cần thêm sự cẩn thận để nó cũng là một chương trình C ++ có cùng ý nghĩa. (Thực tiễn này không phải là chưa từng được biết đến và phương ngữ mà nó yêu cầu được biết đến một cách không chính thức là "Clean C").

Một ví dụ đơn giản về chương trình C bị hỏng khi được coi là C ++ là bất kỳ chương trình C nào sử dụng từ khóa C ++ làm số nhận dạng, chẳng hạn như classhoặc virtual. Objective C không giới thiệu bất kỳ từ khóa dành riêng nào. Nó có các từ khóa mới được giới thiệu bởi @nhân vật, như @interface.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.