¿Qué significa exactamente "Objective-C es un superconjunto de C más estrictamente que C ++"?

87

De lo que leí allí: ¿Por qué Objective-C no es muy popular fuera de la comunidad de Apple?

Objective-C es un superconjunto de C (de hecho, mucho más estrictamente que C ++), por lo que no surge el problema de la compatibilidad con versiones anteriores. Todo lo que puede hacer en C, lo puede hacer en Objective-C.

Ser un superconjunto es binario, como estar embarazada. Obj-C es un superconjunto de C y C ++ no lo es.

¿Qué quieren decir con superconjunto? ¿De qué manera el objetivo-C sería más cercano // compatible con versiones anteriores de C? ¿De qué manera objetivo-C sigue la filosofía de C más de cerca que C ++?

¿Se puede compilar cualquier programa en C sin modificaciones mediante un compilador de objetivo-C (compatibilidad 100%)?

Esta es más una pregunta sobre el diseño y la compatibilidad del lenguaje de programación que una guerra sobre cuál es mejor.

usuario1115057
fuente

Respuestas:

134

Preparé un diagrama simple; no es muy bonito, pero es de esperar que transmita el punto:

  • Rojo: el conjunto de todos los programas válidos en C, C ++ y Objective-C (relativamente pequeño)
  • Verde: el conjunto de todos los programas válidos en C y Objective-C, pero no válidos en C ++ (incluso más pequeños)
  • Gris: el conjunto de todos los programas válidos en Objective C y C ++, pero no válido en C (vacío, hasta donde yo sé)
  • Azul: el conjunto de todos los programas válidos solo en el Objetivo C (relativamente grande)
  • Amarillo: el conjunto de todos los programas válidos solo en C ++ (más grande)

El conjunto de programas C válidos (en rojo y verde) es un subconjunto estricto del conjunto de programas Objective C válidos (azul)

ingrese la descripción de la imagen aquí

Escualo
fuente
14
¿Qué pasa con el objetivo C ++?
user1115057
14
Extraño parecido ...: justindomke.files.wordpress.com/2008/11/scalaimage11.png
user1115057
19
¿En qué medida afirma que el amarillo es "más grande" que el azul aquí? La intuición me dice que ambos conjuntos serían infinitos numerables.
wim
4
@wim: Y ambos se representan como subconjuntos incontables de R ^ 2;) Este es el mismo truco que verá N dentro de la Q a pesar de que tienen el mismo tamaño (y N es un subconjunto estricto de Q).
Maciej Piechotka
3
Estaba pensando en ello un poco más y me di cuenta de que el conjunto de ObjC ++ en realidad no rodearía todo esto. Es un superconjunto de C ++, pero no un superconjunto estricto de ObjC. Los mismos programas que son C legal, pero C ++ ilegal (el área verde) son ObjC ++ ilegal.
Rob Napier
62
  1. ¿Qué quieren decir con superconjunto?

    Significan superconjunto estricto. Cualquier programa C válido se compilará con un compilador Objective-C. Algunos programas C válidos no se compilarán con un compilador C ++.

  2. ¿De qué manera el objetivo-C sería más cercano // compatible con versiones anteriores de C?

    He aquí un ejemplo sencillo:

    int *foo = malloc(12);
    

    Compila en C y Objective-C, pero no en C ++. Por supuesto, también hay otros ejemplos.

  3. ¿De qué manera objetivo-C sigue la filosofía de C más de cerca que C ++?

    Todos: Objective-C es un superconjunto estricto de C.

  4. ¿Se puede compilar cualquier programa en C sin modificaciones mediante un compilador de objetivo-C (compatibilidad 100%)?

    Si.

Carl Norum
fuente
2
Si, eso estaría bien. Podría decirse que tampoco necesita Objective-C para la GUI, si está dispuesto a descubrir las funciones de tiempo de ejecución de bajo nivel que debe usar.
Carl Norum
3
Mayormente filosófico.
Carl Norum
2
+1 Gran explicación. Sugeriría que la cuestión de la "filosofía C" es un poco vaga, pero la mayoría de los observadores probablemente estarían de acuerdo en que los "objetivos" de C y los "objetivos" de ObjC difieren. La intención de C es estar muy cerca del hardware, al tiempo que proporciona algunas abstracciones de portabilidad útiles, mientras que el objetivo de ObjC es llevar un enfoque SmallTalk a C. Como Cocoa se ha convertido en parte integral de ObjC en los últimos años, esta divergencia es aún más fuerte. La "filosofía" (enfoque de diseño) de un C-array y un NSArray son ciertamente muy diferentes.
Rob Napier
2
Eso depende enteramente del programa. Probablemente no haría demasiadas cosas de estilo C en un programa Objective-C. ¿Por qué usarías Objective-C entonces?
Carl Norum
1
@ user1115057: no debe preocuparse demasiado por cómo se consideran las cosas. Hay dos problemas al escribir código C ++ que se compila como (o al menos parece) C. Uno es que no está obteniendo ninguno de los beneficios de C ++, pero esa es su decisión. La importante es que está escribiendo en un dialecto roto de C que no es realmente C. Debería compilar su código C con un compilador C y vincularlo con su código C ++. Esta última preocupación no se aplica con Objective-C, ya que el subconjunto de Objective-C que se compila como C es C.
Steve Jessop
31

Desde cero, C ++ ha sido diseñado como un "C mejor", solucionando omisiones de diseño, tanto reales como percibidas, a medida que los autores de C ++ pasaban por el lenguaje. El resultado de esta decisión de diseño ha sido que Xser un programa C válido no garantiza que Xse compile, y mucho menos se ejecute, cuando sea procesado por el compilador de C ++. Los cambios tocaron construcciones básicas como cadenas literales (se convirtieron en const char*), asignación de voidpunteros, conversiones entre enumsy tipos integrales, semántica de operadores de asignación compuesta , etc.

Además, una vez que apareció C99, las características que se convirtieron en el estándar C actualizado se dejaron fuera del estándar C ++ actualizado. Nuevamente, se omitieron características muy importantes del lenguaje, en particular, inicializadores designados y matrices de tamaño variable.

Por el contrario, Objective C se ha posicionado como un superconjunto de C, lo que requiere que todos los programas C válidos sean compilables con un compilador de Objective C.

Sergey Kalinichenko
fuente
4
Respondí esta pregunta porque sé lo que es un "superconjunto", pero no sé nada sobre Objective-C. He visto una afirmación en otra pregunta SO, que el fragmento de código C válido int nil = 0; nil++;no se compila como Objective-C. ¿Cuál es el problema allí? ¿Es obvio que Objective-C hace disponibles encabezados que, una vez incluidos, pueden romper su código exactamente como lo hacen los encabezados C? Y por lo tanto, el autor de ese fragmento no debería haberlos incluido.
Steve Jessop
2
"nil" es en realidad una #define en lugar de una palabra clave. Estás viendo problemas porque objc / objc.h está incluido. Esto es similar a los problemas que vería si intentara crear una variable llamada YES. (Xcode destaca estos como si fueran realmente palabras clave porque es mucho más fácil pensar en ello de esa manera; pero están implementados como código C simple).
Rob Napier
4
Por cierto, vale la pena hurgar un poco en objc.ha poco si estás interesado en cómo vive ObjC además de C.Las cosas que pensarías que serían palabras clave (id, BOOL, Class, nil, etc.) son solo tipos simples, estructuras y define. Incluso puede implementar el paso de mensajes a mano en pure-C. Nunca jamás hagas eso. : D Pero puedes. github.com/iosptl/ios6ptl/blob/master/ch28/Runtime/MyMsgSend.c
Rob Napier
2
@DanNeely: Rob Napier dijo "nunca, nunca hagas eso" como comentario sobre el archivo vinculado. El archivo vinculado no es el tiempo de ejecución de Objective-C, es solo un truco rápido que muestra cómo funciona realmente la mensajería.
Dietrich Epp
1
El archivo vinculado no demostraba lo complicado que es el paso de mensajes de ObjC. Demuestra que el tiempo de ejecución está disponible en C y que, en principio, puede convertir el código ObjC en C. puro, PERO ... esto es tan lento como podría construirlo. Se basó en que yo conociera el tipo de retorno de los métodos (y para algunos tipos de retorno, probablemente necesitaría saber el tipo de procesador), y elegí cuidadosamente los métodos que no toman parámetros. La solución completa tiene muchos trucos sutiles (las piezas deben estar en ensamblador porque hacen trampa con los marcos de la pila). Nunca debería intentar reconstruirlo.
Rob Napier
12

"Objective-C es un superconjunto de C" significa que cada programa C válido es un programa Objective-C válido (con el mismo significado).

A veces se dice, aunque no lo hacen los expertos en C ++, que C ++ es un superconjunto de C. Esto no es exacto, por lo que su cita está haciendo un gran problema al comparar los dos.

Steve Jessop
fuente
9

Objective C es un conjunto de extensiones compatibles con versiones anteriores de C. Esto es posible porque las características de Objective C están delimitadas de dos formas muy simples:

  • uso del personaje @. Este carácter no se usa actualmente en el lenguaje C.
  • una simple extensión sintáctica para invocar métodos, [obj method:argument]. En C, los corchetes se usan de una manera muy específica para el subíndice de matrices, por lo que esta sintaxis C no es válida. Las extensiones que se basan en una sintaxis no válida no cambian el significado de nada que sea válido en el idioma anfitrión.

Es tan fácil de ver que ningún programa que use extensiones Objective C puede ser un programa ISO C estrictamente conforme, no importa lo simple que sea. Además, cada programa ISO C puede declararse, por definición, como un programa Objective C válido. Objective C puede seguir fácilmente desarrollos como C99 y C11.

Por otro lado, C ++ no son simplemente extensiones de C; es un lenguaje diferente que cambia el significado de algunas de las sintaxis de C. C ++ y C se mantienen por separado, por lo que su relación cambia con el tiempo. Por ejemplo, C ha adquirido nuevas características que están completamente ausentes en C ++, y es muy probable que no entren en C ++, como las matrices de longitud variable C99. C ++ no puede recoger fácilmente nuevas características de C.

Si escribe un programa portátil en C, debería ser al mismo tiempo un programa Objective C. Pero se necesitará un cuidado adicional para que también sea un programa C ++ con el mismo significado. (Esta práctica no es desconocida, y el dialecto que requiere se conoce informalmente como "Clean C").

Un ejemplo trivial de un programa en C que se rompe cuando se trata como C ++ es cualquier programa en C que utiliza una palabra clave de C ++ como identificador, como classo virtual. El objetivo C no introduce palabras clave reservadas. Tiene nuevas palabras clave que son introducidas por el @personaje, como @interface.

Kaz
fuente