6

Can anyone explain how @encode works to extract the datatype elements present in a given object, struct, or datatype into a type definition to be used as a class descriptor for instantiation?

Or maybe a pointer to some resources for learning about the implementation of new preprocessor directives?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Anderson
  • 327
  • 3
  • 10
  • I'm thinking its just a function-type macro that somehow parses and stringifies what is passed to it – Anderson Feb 11 '10 at 20:51
  • Just curious, how does the `@encode` relate to the C language (which doesn't have this keyword)? I suggest removing the 'c' tag. – Thomas Matthews Feb 11 '10 at 23:27
  • 1
    `@encode` is not a preprocessor directive, it relies on type information such as the size of types, something that the preprocessor is not aware of. – dreamlax Feb 11 '10 at 23:29
  • @Thomas I'm trying to do the equivalent of Objective-C's @encode in ANSI C. So the c tag is relevant. – Anderson Feb 12 '10 at 00:34
  • @dreamlax I assumed the same but how does it realize the datatype construction of a struct? If you do sizeof(struct aStruct) only the size of the full struct is returned how would you determine all the data elements that make up the struct? – Anderson Feb 12 '10 at 00:37
  • @dreamlax The runtime reference you linked to in your answer states it as such... (Is there a difference between compiler directive and preprocessor directive?) "To assist the runtime system, the compiler encodes the return and argument types for each method in a character string and associates the string with the method selector. The coding scheme it uses is also useful in other contexts and so is made publicly available with the @encode() COMPILER DIRECTIVE." – Anderson Feb 12 '10 at 00:41
  • A compiler directive and a preprocessor directive are two entirely different things. A preprocessor directive tells the preprocessor what to do, whereas a compiler directive tells the compiler what to do. – dreamlax Feb 12 '10 at 01:00
  • I think perhaps it's best to deepen your understanding of how a compiler generally works, before trying to understand what specific parts of a compiler do. – dreamlax Feb 12 '10 at 01:02
  • @dreamlax makes sense; I though they were all called compiler directives only some did something with the preprocessor specifically. But I think we're getting way off track from the original question – Anderson Feb 12 '10 at 22:26

2 Answers2

5

The @encode directive parses the provided type and generates a constant string based on that type. The encoding of all C primitive types (including signed and unsigned versions) and the Objective-C id and SEL types all have single-character encodings, these can be found in <objc/runtime.h>. More complicated types such as structs and arrays have larger encodings.

More information is available in the Objective-C Runtime Programming Guide [PDF].

dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • Thanks for your help but I know WHAT it does. I'm interested in HOW it does it. – Anderson Feb 12 '10 at 00:47
  • 2
    Once the source has been parsed into an ASTs, the `@encode` method probably traverses the tree and inspects the individual types and generates the string from that. – dreamlax Feb 12 '10 at 00:58
  • The way I understand it is that at compile-time, Type Descriptors are generated using the @encode directive with the contents of each class's @interface header. These type descriptors are stored inside the binary and the .ctors section instantiates each class object at run-time using the __attribute__((constructors)) function. – Anderson Feb 12 '10 at 02:37
  • So how can you introspect an opaque struct object if it is not a full-fledged object yet? – Anderson Feb 12 '10 at 02:41
  • @Anderson: you can't. The encoding of an incomplete `struct` is also incomplete. – dreamlax Feb 12 '10 at 02:55
  • Also, what has `@encode` got to do with interface headers? Or constructors? – dreamlax Feb 12 '10 at 02:55
  • My overall purpose of this question and my previous one: http://stackoverflow.com/questions/2219501/how-does-the-objective-c-runtime-instantiate-the-root-metaclass-and-other-class-d is to gain knowledge in how Objective-C uses the interface header to create the metaclass and class objects which must be available at runtime in order to instantiate objects. – Anderson Feb 12 '10 at 16:54
  • I'm following http://www.planetpdf.com/codecuts/pdfs/ooc.pdf as a guide to implementing a basic ooc implementation. Rather than hard code every class description manually, I'm interested in how Objective-C does it (I've been told it uses @encode to build Type Descriptors at compile-time) to get an idea of how I could do it myself. – Anderson Feb 12 '10 at 16:59
  • Objects are not required... This works... how does it do it? ('struct test { int ti ; char tc ; } ; char * encodedstruct = @encode(struct test) ; printf("%s", encodedstruct ) ;') – Anderson Feb 12 '10 at 18:29
  • 3
    It's done at compile time *by the compiler*. The compiler is fully aware of each type, its size, and its signedness. You cannot implement something like this outside the compiler unless you create a static analyser to perform the same task. – dreamlax Feb 12 '10 at 23:10
1

The phrasing of the original question may have been unclear and I think that my mentioning of a possible implementation involving the preprocessor caused the conversation to turn toward the subtleties of how compilers work rather than the intended question.

Please reference this question, which I believe is much more clear as to what I'm trying to learn: How would I implement something similar to the Objective-C @encode() compiler directive in ANSI C?

Community
  • 1
  • 1
Anderson
  • 327
  • 3
  • 10
  • 2
    It can't be done in the preprocessor because the preprocessor is completely unaware of any type information. – dreamlax Feb 12 '10 at 23:06