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 ?
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.
Related
I guess there must be a duplicated question here but I couldn't find it. I'm recently working on a C project and, while trying to leave the code as concise as possible, I considered typedef-ing a consistently-used array with a certain type.
As an example, suppose the array of a structure type entry has always the fixed length of MAX_N_ENTRIES. I'd like to reduce the redundancy by rewriting the code;
struct entry ents[MAX_N_ENTRIES];
to this code;
typedef struct entry entry_arr_t[MAX_N_ENTRIES];
entry_arr_t ents;
What I'm concerning about is that, as the array type obviously should be handled in a different way to any primitive types in C, this kind of typedef-ing can cause confusion in the future, making it look like an alias of primitives.
Yes, it's possible to create a typedef for an array type -- and there's even an example in the Standard C library, namely the jmp_buf type that's used with setjmp and longjmp.
It's usually considered poor style, however, because type names are usually assumed to refer to first-class types that you can do every ordinary first-class-type thing with, and in particular: assign them. But of course you can't assign arrays in C, because they're not first-class types.
In other words, given the typedef in your question, a later programmer might assume that it would be possible to write
entry_arr_t ents1, ents2;
...
ents1 = ents2;
But of course that assignment would fail.
The fact that you've included "arr" in the typedef name does indeed mitigate this concern, making it less likely that the hypothetical later programmer would make the bad assumption.
when doing inheritance in pure C like this
typedef struct {
char name[NAMESIZE];
char sex;
} Person;
typedef struct {
Person person;
char job[JOBSIZE];
} Employee;
typedef struct {
Person person;
char booktitle[TITLESIZE];
} LiteraryCharacter;
I know it is okay to cast a instance of type "LiteraryCharacter" to type "Person", and use it as such. But is it also ok/safe to cast a instance of type "LiteraryCharacter" to type "Employee" and use it as such?
Such a cast is undefined behavior in standard C, although it will work with many compilers.
Even if it works on a compiler you are currently using, be aware that it might break in a future version of the compiler, or with a different compiler. The C standard allows the compiler to assume that pointers to different types don't point to the same memory - except for some well-documented exceptions, which include cast of LiteraryCharacter * to Person *. The code that casts LiteraryCharacter * to Employee * can and will break under a compiler that makes use of this assumption to generate efficient code.
It might be a good idea to explain why you think you need this cast in the first place. Its equivalent would be quite incorrect in C++, and generate a ClassCastException in Java. After all, LiteraryCharacter doesn't have the fields of Person, such as job.
That would be undefined behaviour. There is no such thing as inheritance in C.
You might get away with it if the structures had exactly the same layout but that would be very brittle code indeed.
Undefined behavior:
In your example you are casting to-from incompatible types which doesn't even compile because of the differences in the sizes of those two types. You can however cast to-from compatible (or even incompatible) pointer types and it will compile.
Casting to-from incompatible (or rather pseudo-compatible) types is undefined behavior, on some structures and compiler implementations it will work on others it won't.
Casting to compatible -- pointer types is safe as long as the compiler is taking care of the object structure / internal alignments / memory layout, etc. (there's an example below).
The "OK" part is debatable. Will it work? Yes because they have the same "in memory" layout and you are aware of that particular fact. But what happens when another programmer created that structure? You have to read its source to assess if it can be safely cast to another type.
Encapsulation and future proofing:
Also most encapsulation techniques will only expose an "opaque type" which you can use via pointers -- pass it along to functions implemented within the same library/package and they do all of the structure specific work. In the case of "opaque types" you only know that that structure exists, you don't know it's internal structure so you can't just change the pointer type you're using to access it because you can't be sure of the structure compatibility behind it.
The point of encapsulation is to allow modules to be developed individually. So when the original developer of this external module changes the structure in a future version it breaks compatibility with your code (which shouldn't be using it that way anyway).
Safer way to do this:
This is a non standard (yet pretty much ubiquitous) compiler feature of GCC.
typedef struct {
char name[NAMESIZE];
char sex;
} Person;
typedef struct {
Person;
char job[JOBSIZE];
} Employee;
typedef struct {
Employee;
char booktitle[TITLESIZE];
} LiteraryEmployeeCharacter;
LiteraryEmployeeCharacter* lec = malloc(sizeof(LiteraryEmployeeCharacter));
lec->name = "My character";
lec->sex = 'F';
lec->job = "Steward";
lec->booktitle = "A book";
By using unnamed fields you get access to name, sex and job as if they were defined in the LiteraryEmployeeCharacter structure.
By casting to a compatible pointer type the compiler knows the exact structure and position of every field and ca easily handle the structure correctly.
I recently came across a colleague's code that looked like this:
typedef struct A {
int x;
}A;
typedef struct B {
A a;
int d;
}B;
void fn(){
B *b;
((A*)b)->x = 10;
}
His explanation was that since struct A was the first member of struct B, so b->x would be the same as b->a.x and provides better readability.
This makes sense, but is this considered good practice? And will this work across platforms? Currently this runs fine on GCC.
Yes, it will work cross-platform(a), but that doesn't necessarily make it a good idea.
As per the ISO C standard (all citations below are from C11), 6.7.2.1 Structure and union specifiers /15, there is not allowed to be padding before the first element of a structure
In addition, 6.2.7 Compatible type and composite type states that:
Two types have compatible type if their types are the same
and it is undisputed that the A and A-within-B types are identical.
This means that the memory accesses to the A fields will be the same in both A and B types, as would the more sensible b->a.x which is probably what you should be using if you have any concerns about maintainability in future.
And, though you would normally have to worry about strict type aliasing, I don't believe that applies here. It is illegal to alias pointers but the standard has specific exceptions.
6.5 Expressions /7 states some of those exceptions, with the footnote:
The intent of this list is to specify those circumstances in which an object may or may not be aliased.
The exceptions listed are:
a type compatible with the effective type of the object;
some other exceptions which need not concern us here; and
an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union).
That, combined with the struct padding rules mentioned above, including the phrase:
A pointer to a structure object, suitably converted, points to its initial member
seems to indicate this example is specifically allowed for. The core point we have to remember here is that the type of the expression ((A*)b) is A*, not B*. That makes the variables compatible for the purposes of unrestricted aliasing.
That's my reading of the relevant portions of the standard, I've been wrong before (b), but I doubt it in this case.
So, if you have a genuine need for this, it will work okay but I'd be documenting any constraints in the code very close to the structures so as to not get bitten in future.
(a) In the general sense. Of course, the code snippet:
B *b;
((A*)b)->x = 10;
will be undefined behaviour because b is not initialised to something sensible. But I'm going to assume this is just example code meant to illustrate your question. If anyone's concerned about it, think of it instead as:
B b, *pb = &b;
((A*)pb)->x = 10;
(b) As my wife will tell you, frequently and with little prompting :-)
I'll go out on a limb and oppose #paxdiablo on this one: I think it's a fine idea, and it's very common in large, production-quality code.
It's basically the most obvious and nice way to implement inheritance-based object oriented data structures in C. Starting the declaration of struct B with an instance of struct A means "B is a sub-class of A". The fact that the first structure member is guaranteed to be 0 bytes from the start of the structure is what makes it work safely, and it's borderline beautiful in my opinion.
It's widely used and deployed in code based on the GObject library, such as the GTK+ user interface toolkit and the GNOME desktop environment.
Of course, it requires you to "know what you're doing", but that is generally always the case when implementing complicated type relationships in C. :)
In the case of GObject and GTK+, there's plenty of support infrastructure and documentation to help with this: it's quite hard to forget about it. It might mean that creating a new class isn't something you do just as quickly as in C++, but that's perhaps to be expected since there's no native support in C for classes.
That's a horrible idea. As soon as someone comes along and inserts another field at the front of struct B your program blows up. And what is so wrong with b.a.x?
Anything that circumvents type checking should generally be avoided.
This hack rely on the order of the declarations and neither the cast nor this order can be enforced by the compiler.
It should work cross-platform, but I don't think it is a good practice.
If you really have deeply nested structures (you might have to wonder why, however), then you should use a temporary local variable to access the fields:
A deep_a = e->d.c.b.a;
deep_a.x = 10;
deep_a.y = deep_a.x + 72;
e->d.c.b.a = deep_a;
Or, if you don't want to copy a along:
A* deep_a = &(e->d.c.b.a);
deep_a->x = 10;
deep_a->y = deep_a->x + 72;
This shows from where a comes and it doesn't require a cast.
Java and C# also regularly expose constructs like "c.b.a", I don't see what the problem is. If what you want to simulate is object-oriented behaviour, then you should consider using an object-oriented language (like C++), since "extending structs" in the way you propose doesn't provide encapsulation nor runtime polymorphism (although one may argue that ((A*)b) is akin to a "dynamic cast").
I am sorry to disagree with all the other answers here, but this system is not compliant to standard C. It is not acceptable to have two pointers with different types which point to the same location at the same time, this is called aliasing and is not allowed by the strict aliasing rules in C99 and many other standards. A less ugly was of doing this would be to use in-line getter functions which then do not have to look neat in that way. Or perhaps this is the job for a union? Specifically allowed to hold one of several types, however there are a myriad of other drawbacks there too.
In short, this kind of dirty casting to create polymorphism is not allowed by most C standards, just because it seems to work on your compiler does not mean it is acceptable. See here for an explanation of why it is not allowed, and why compilers at high optimization levels can break code which does not follow these rules http://en.wikipedia.org/wiki/Aliasing_%28computing%29#Conflicts_with_optimization
Yes, it will work. And it is one of the core principle of Object Oriented using C. See this answer 'Object-orientation in C' for more examples about extending (i.e inheritance).
This is perfectly legal, and, in my opinion, pretty elegant. For an example of this in production code, see the GObject docs:
Thanks to these simple conditions, it is possible to detect the type
of every object instance by doing:
B *b;
b->parent.parent.g_class->g_type
or, more quickly:
B *b;
((GTypeInstance*)b)->g_class->g_type
Personally, I think that unions are ugly and tend to lead towards huge switch statements, which is a big part of what you've worked to avoid by writing OO code. I write a significant amount of code myself in this style --- typically, the first member of the struct contains function pointers that can be made to work like a vtable for the type in question.
I can see how this works but I would not call this good practice. This is depending on how the bytes of each data structure is placed in memory. Any time you are casting one complicated data structure to another (ie. structs), it's not a very good idea, especially when the two structures are not the same size.
I think the OP and many commenters have latched onto the idea that the code is extending a struct.
It is not.
This is and example of composition. Very useful. (Getting rid of the typedefs, here is a more descriptive example ):
struct person {
char name[MAX_STRING + 1];
char address[MAX_STRING + 1];
}
struct item {
int x;
};
struct accessory {
int y;
};
/* fixed size memory buffer.
The Linux kernel is full of embedded structs like this
*/
struct order {
struct person customer;
struct item items[MAX_ITEMS];
struct accessory accessories[MAX_ACCESSORIES];
};
void fn(struct order *the_order){
memcpy(the_order->customer.name, DEFAULT_NAME, sizeof(DEFAULT_NAME));
}
You have a fixed size buffer that is nicely compartmentalized. It sure beats a giant single tier struct.
struct double_order {
struct order order;
struct item extra_items[MAX_ITEMS];
struct accessory extra_accessories[MAX_ACCESSORIES];
};
So now you have a second struct that can be treated (a la inheritance) exactly like the first with an explicit cast.
struct double_order d;
fn((order *)&d);
This preserves compatibility with code that was written to work with the smaller struct. Both the Linux kernel (http://lxr.free-electrons.com/source/include/linux/spi/spi.h (look at struct spi_device)) and bsd sockets library (http://beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html) use this approach. In the kernel and sockets cases you have a struct that is run through both generic and differentiated sections of code. Not all that different than the use case for inheritance.
I would NOT suggest writing structs like that just for readability.
I think Postgres does this in some of their code as well. Not that it makes it a good idea, but it does say something about how widely accepted it seems to be.
Perhaps you can consider using macros to implement this feature, the need to reuse the function or field into the macro.
I have a header and a sample application using this header, all in C, I get almost all the logic of this software except for this; this the interesting part of the header:
struct A;
typedef struct A A;
in the C application this A is only used when declaring a pointer like this
A* aName;
I'm quite sure that this is a solution for just including A in the scope/namespace and give just a name to a basically void pointer, because this kind of pointer is only used to handle some kind of data, it is more like some namespace sugar.
What this could be for?
You're correct that it's like a void pointer, in that void is an incomplete type, and in this file A is also an incomplete type. About all you can do with incomplete types is pass around pointers to them.
It has one advantage over void* in this file, that it's a different and incompatible type from some other bit of code that has done the same thing with B. So you get a bit of type safety. If A is windowHandle and B is jpgHandle, then you can't pass the wrong one to a function.
It has an advantage over void* in the .c file that defines the functions that accept an A* -- that file can contain a definition of struct A, and give A whatever members it wants, that the first file doesn't need to know about.
However, you say there are no other mentions of A in any header file, which means there are no functions that accept or return it. You also say that the only use of A in your source file is to declare pointers -- I wonder where the values of those pointers come from, if any.
If all that happens if that someone defines an uninitialized A* and never uses it, then clearly this is a remnant of some old code, or the start of some code that never got written, and it shouldn't be in the file at all.
Finally, if the real type is called something a bit less stupid than A, then the name might give a clue to its use.
I assume struct A is a forward declaration. It most likely is defined in one of the .c-files.
Doing so struct A's members are private to the module defining it.
This is an example of an opaque pointer, which is useful for passing handles. See http://en.wikipedia.org/wiki/Opaque_pointer for some further info. What may be interesting here from a C++ perspective, is the notion that you can define a class with a member that is a pointer to an (as yet) undefined struct. Although this struct is thus not yet defined in the header, in some later cpp implementation this struct is given body, and the compiler does the rest. This strategy is also called the Pimpl idiom (more of which you will find LOTS on the internet). Microsoft discusses it briefly at http://msdn.microsoft.com/en-us/library/hh438477.aspx.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Typedef pointers a good idea?
I've seen this oddity in many APIs I have used:
typedef type_t *TYPE;
My point is that declaring a variable of type TYPE will not make it clear that in fact a pointer is declared.
Do you, like me, think that this brings a lot of confusion? Is this meant to enforce encapsulation, or there are other reasons as well? Do you consider this to be a bad practice?
In general, it's a bad practice. The significant problem is that it does not play well with const:
typedef type_t *TYPE;
extern void set_type(TYPE t);
void foo(const TYPE mytype) {
set_type(mytype); // Error expected, but in fact compiles
}
In order for the author of foo() to express what they really mean, the library that provides TYPE must also provide CONST_TYPE:
typedef const type_t *CONST_TYPE;
so that foo() can have the signature void foo(CONST_TYPE mytype), and at this point we have descended into farce.
Hence a rule of thumb:
Make typedefs of structs (particularly incomplete structs), not pointers to those structs.
If the definition of the underlying struct is not to be publicly available (which is often laudable), then that encapsulation should be supplied by the struct being incomplete, rather than by inconvenient typedefs:
struct type_t;
typedef struct type_t type_t;
void set_type(type_t *);
int get_type_field(const type_t *);
A common idiom is to suffix the type with _p to indicate that it's a pointer while still retaining the pointery qualities.
Sometimes it is necessary to use only the pointer type if the struct that it is pointing to is not publicly available. This helps facilitate data hiding. I.e.
typedef struct hidden_secret_object * object;
void change_object(object foo);
this allows you to change the way that hidden_secret_object is structured without breaking external code.
I don't find it clear either. I'm not fond of full capitalised types either (I try to reserve those for #defines).
This way makes it easy to kid oneself by thinking it is in fact a value type, while we're talking about a pointer type. The pointer type can be completely abstracted away with smart pointers, but that isn't common practise in C.
Suffixing with (as mentioned previously) _p, _ptr, Pointer or anything along those lines creates clarity; increases typing, that's true, but will prevent you from silly mistakes (such as using '.' instead of '->', ...) costing you valuable developing time.
It depends on what you are trying to achieve. There is no meaningful "yes or no" answer to your question the way it is stated.
If you are trying to create an abstract handle kind of type, implying that the user is not supposed to know or care what is hiding behind the type, then typedef-ing a pointer type is perfectly fine. The whole point is that today it might be a pointer type, and tomorrow it might become an integer type, and later it might become something else. This is exactly what pointer type typedefs are normally used for in most library interfaces.
You are saying that sometimes it is "not clear that a pointer is declared". But under this usage model that's exactly the point! It is supposed to be "not clear". The fact that the type happens to be an obfuscated pointer is none of your business. It is something that you don't need to know and not supposed to rely upon.
A classic example of this usage model is the va_list type in the standard library. In some implementation it might easily be a typedef for a pointer type. But that's something you are not supposed to know or rely upon.
Another example would be the definition of HWND type in Windows API. It is a typedef for pointer type as well, but that's none of your business.
A completely different situation is when you are typedef-ing a pointer type as a form of shorthand, just to make the declarations shorter for not having to type the * character every time. In this case the fact that the typedef is (and will always be) standing for a pointer type is exposed to the user. Normally this usage is not a good programming practice. If the users will want to create an alias to avoid typing * every time, they can do it by themselves.
This usage model usually leads to more obfuscated code for the reasons you already mentioned in your OP.
Example of this bad usage of typedefs can also be found in Windows API. Typedef names like PINT follow exactly that flawed usage model.
I don't think it's bad practice if the it's a pointer to an incomplete type, or if for any other reason the user isn't expected to dereference it. I never understood FILE*.
I also don't think it's bad practice if you're doing it because you have several levels of indirection, and you want to use it in situations where some of them are irrelevant. typedef char **argarray, or something.
If the user is expected to dereference it then in C, I think it's probably best to retain the *. In C++, people are used to user-defined types with overloaded operator*, such as iterators. In C that's just not normal.
Storage-class qualifiers like 'const' will work differently with typedef'ed pointers than with 'natural' ones. While this isn't typically a good thing with 'const', it can be very useful with compiler-specific storage classes like "xdata". A declaration like:
xdata WOKKA *foo;
will declare "foo" to be a pointer, stored in the default storage class, to a WOKKA in xdata. A declaration:
xdata WOKKA_PTR bar;
would declare "bar" to be a pointer, stored in xdata, to a WOKKA in whatever storage class was specified in WOKKA_PTR. If library routines are going to expect pointers to things with a particular storage class, it may be useful to define those storage classes within the pointer types.
It's bitten me in the ass on occasion:
for (vector<typedef_name_that_doesnt_indicate_pointerness_at_all>::iterator it;
it != v.end(); ++it)
{
it->foo(); // should have been written (*it)->foo();
}
The only time it's acceptable is if the type is meant to be truly opaque and not accessed directly at all. IOW, if someone's going to have to dereference it outside of an API, then the pointerness should not be hidden behind a typedef.
Maybe a way to make it more specific would be to call the new pointer type type_ptr or something like that:
typedef type_t* type_ptr;