0

I've read the last C++11 draft (n3337 - is it the last one?), and I got a question for a possible implementation I've been working on.

Let's say we have this code:

extern "Objective C" {
  class Object {
    public:
      static Object *alloc();
      Object *init();
  };
};

Then calling

Object *x = Object::alloc()->init();

The question is that I didn't understand if it is allowed for the compiler to control the calling convention of extern "X" blocks: the idea would be to "translate" the calls to objc_msgSend(blablabla) - would that be conformant to the standard, or would it be considered an extension (since it wouldn't just modify the symbol name, but as well as a complex "calling convention" here)? Of course I could implement this by making a weak function that is called as __thiscall and then calls and returns the method itself - but the question continues, would it be conformant?

Thanks!

paulotorrens
  • 2,286
  • 20
  • 30

1 Answers1

1

Everything you describe sounds to be in line with the intent of the language linkage feature.

Class members are specifically excluded from "C" language linkage. According to examples in the Standard (C++11 §7.5/4), function pointer types within class member declarations, extern declarations in any context, and all other function declarations do inherit the enclosing extern "C" {} block. You're defining a language linkage besides "C" but it would be least surprising to follow its example, perhaps with extra mapping between this and self.

The requirements are open, according to §7.5/2:

Use of a string-literal other than "C" or "C++" is conditionally-supported, with implementation-defined semantics. [ Note: Therefore, a linkage-specification with a string- literal that is unknown to the implementation requires a diagnostic. — end note ] [ Note: It is recommended that the spelling of the string-literal be taken from the document defining that language. For example, Ada (not ADA) and Fortran or FORTRAN, depending on the vintage. — end note ]

You could switch to a completely different language within the braces an it would be alright. (Although, grammatically, I suppose everything should parse as a C++ declaration or declaration-seq.)

According to that, though, you should use extern "Objective-C" with a hyphen since the definitive document's title is "The Objective-C Programming Language."

EDIT: To be sure, calling through objc_msgSend doesn't affect anything that the Standard specifies. Nowhere does it say how C++ functions are called. The added intermediate function is just machine-level instructions, beyond language semantics, and no different from the special instructions used to call into Pascal, Fortran, etc., e.g. by altering the order of parameters on the stack. I don't mean to compare your scheme to "switching to a completely different language within the braces," just to emphasize that there's plenty of headroom.

Taking the extern "C" specification in the Standard as an example, it breaks a lot of things by fundamentally changing the ODR rule because C isn't required to support any mangling. So your scheme is allowed to break at least that much.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • The contents of the class are excluded only when having C linkage, according to the standard. :) – paulotorrens Jan 31 '13 at 01:53
  • @PauloTorrens So it is. Will fix answer. – Potatoswatter Jan 31 '13 at 01:55
  • Thansk for the answer. Now I only have to think how I am supposed to map the colons so that you could call any message. :3 – paulotorrens Jan 31 '13 at 06:12
  • 1
    @PauloTorrens Three options: 1. The `@` and `$` signs are unused but already get lexed as letters by many implementations. (I suppose you're building on Clang, not sure but it's definitely worth looking at.) 2. The double underscore `__` is reserved to the system, so you can somewhat safely use that, although some idiots put things like that in identifiers. 3. You could extend function argument syntax to support the colon; I don't see why this wouldn't work. Although it would of course be non-compliant, it would be very nice and it could just map to one of the other options. – Potatoswatter Jan 31 '13 at 06:35
  • Actually, my own project [black](http://black.nongnu.org), I'm working on easier bindings across languages now. The problem is that I find Objective-C++ kinda ugly. I tried using colons to see what compilers would say, and since they all complained about the wrong "Objective-C" linkage before the colon... although I think it would be better to map to something. Maybe using an [[attribute]]? – paulotorrens Jan 31 '13 at 06:43
  • @PauloTorrens Cool. Take a look at my project http://code.google.com/p/c-plus , a standalone preprocessor which is mainly a testbed for a C++11 compiler framework. I would recommend against `[[attribute]]`; it will get tedious. Not sure what you were testing against the other compilers but you might conditionally `#define objc "Objective-C"`. You might take the unused names from the forward declarations. You might finaggle things so you can use C99 named initializers and braces for the function call itself a la brace initialization. – Potatoswatter Jan 31 '13 at 06:47