2

How to literally translate the following empty C struct inside struct to Delphi (from winnt.h):

typedef struct _TP_CALLBACK_ENVIRON_V3 {
    ...
    struct _ACTIVATION_CONTEXT        *ActivationContext;
    ...
} TP_CALLBACK_ENVIRON_V3;

I'm inclined to use just Pointer since this structure must not be manipulated and it's a pointer anyway. I'm just curious how would one translate it literally (if possible). I was thinking about something like this:

type
  PActivationContext = ^TActivationContext;
  TActivationContext = record

  end;

  TTPCallbackEnvironV3 = record
    ...
    ActivationContext: PActivationContext;
    ...
  end;

But, you know, an empty record... So, how would you literally translate the above structure to Delphi ?

3
  • 1
    The empty record has the advantage of being a specific and different type, i.e. a pointer to such a record is an opaque pointer to a specific type. Otherwise, there is no difference. I personally prefer the empty record, though. FWIW, in C it is not necessary an empty struct, just an unknown one. Commented Dec 1, 2014 at 17:05
  • @Rudy, but if it's not necessarily an empty struct, shouldn't then an opaque pointer be used ? Commented Dec 1, 2014 at 17:08
  • 2
    @TLama: A pointer to an incomplete structure is quite opaque, I'd say. BTW: There are no empty structures in standard C (though e.g. Gcc allows it as an extension by default). Commented Dec 1, 2014 at 18:35

1 Answer 1

5

The C struct is what is known as an incomplete type. The C code is a common technique used to implement an opaque pointer. By implementing it this way in C you have type safety in the sense that variables of type struct _ACTIVATION_CONTEXT* are not assignment compatible with other pointers. Well, apart from void* pointers which are assignment compatible with all pointer types.

In Delphi there is no such thing as an incomplete type. So I think that the best solution is exactly what you have proposed. It's not particularly important to mimic the C code exactly. What you are aiming for is to have the benefits, specifically type safety. And what you propose is probably as good as you will get.

On the other hand, it depends how visible this type is. If it is very private, perhaps declared only in the implementation section of a unit, and used sparingly, then you may take the stance that declaring an empty record is a little over the top. You may conclude that PActivationContext = Pointer is reasonable.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I will define it as opaque pointer PActivationContext = type Pointer; in real code. I was just wondering about the literal translation. Still, something tells me that an empty record is not correct. If it's a pointer to an incomplete type (which I imagine as a type unknown to the application), I should not define it as a pointer to an empty record at least because there can be void or an array behind the scene. So I think that generic Pointer is the best choice to explain an unknown type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.