Jump to page: 1 2
Thread overview
How to handle nested structs when converting C headers?
Dec 11, 2013
Gary Willoughby
Dec 11, 2013
Adam D. Ruppe
Dec 11, 2013
Adam D. Ruppe
Dec 11, 2013
bearophile
Dec 11, 2013
Gary Willoughby
Dec 11, 2013
Gary Willoughby
Dec 11, 2013
Adam D. Ruppe
Dec 11, 2013
Gary Willoughby
Dec 12, 2013
H. S. Teoh
Dec 12, 2013
Regan Heath
Dec 12, 2013
bearophile
Dec 11, 2013
bearophile
Dec 11, 2013
Adam D. Ruppe
Dec 11, 2013
bearophile
Dec 12, 2013
Jacob Carlborg
December 11, 2013
How to handle nested structs when converting C headers?

In the following snippet i'm currently converting, how would you convert the nested typed union and structures? Would you declare them separately then use their types in the Tcl_Obj struct? or is there a nice way in D to nest them like C?

typedef struct Tcl_Obj {
    int refCount;		/* When 0 the object will be freed. */
    char *bytes;		/* This points to the first byte of the
				 * object's string representation. The array
				 * must be followed by a null byte (i.e., at
				 * offset length) but may also contain
				 * embedded null characters. The array's
				 * storage is allocated by ckalloc. NULL means
				 * the string rep is invalid and must be
				 * regenerated from the internal rep.  Clients
				 * should use Tcl_GetStringFromObj or
				 * Tcl_GetString to get a pointer to the byte
				 * array as a readonly value. */
    int length;			/* The number of bytes at *bytes, not
				 * including the terminating null. */
    Tcl_ObjType *typePtr;	/* Denotes the object's type. Always
				 * corresponds to the type of the object's
				 * internal rep. NULL indicates the object has
				 * no internal rep (has no type). */
    union {			/* The internal representation: */
	long longValue;		/*   - an long integer value. */
	double doubleValue;	/*   - a double-precision floating value. */
	VOID *otherValuePtr;	/*   - another, type-specific value. */
	Tcl_WideInt wideValue;	/*   - a long long value. */
	struct {		/*   - internal rep as two pointers. */
	    VOID *ptr1;
	    VOID *ptr2;
	} twoPtrValue;
	struct {		/*   - internal rep as a wide int, tightly
				 *     packed fields. */
	    VOID *ptr;		/* Pointer to digits. */
	    unsigned long value;/* Alloc, used, and signum packed into a
				 * single word. */
	} ptrAndLongRep;
    } internalRep;
} Tcl_Obj;
December 11, 2013
On Wednesday, 11 December 2013 at 22:45:35 UTC, Gary Willoughby wrote:
> How to handle nested structs when converting C headers?

Nested structs and unions like in your example are supported in D too, same syntax, same effect.
December 11, 2013
On Wednesday, 11 December 2013 at 22:54:04 UTC, Adam D. Ruppe wrote:
> Nested structs and unions like in your example are supported in D too, same syntax, same effect.

Actually, no, not quite the same syntax, I didn't notice the name at the end of the C one (in D, the anonymous nested structs and unions are supported).

But almost the same then: make them a nested type with a name after the struct or union keyword then the member. So

    struct TwoPtrValue {                /*   - internal rep as two pointers. */
            VOID *ptr1;
            VOID *ptr2;
        }
     TwoPtrValue twoPtrValue;

that's how I'd do it
December 11, 2013
Adam D. Ruppe:

> Nested structs and unions like in your example are supported in D too, same syntax, same effect.

But don't forget to add to use "static struct" instad of "struct".

Bye,
bearophile
December 11, 2013
On Wednesday, 11 December 2013 at 23:12:39 UTC, bearophile wrote:
> Adam D. Ruppe:
>
>> Nested structs and unions like in your example are supported in D too, same syntax, same effect.
>
> But don't forget to add to use "static struct" instad of "struct".
>
> Bye,
> bearophile

Have you got an example because i always get:

tcl.d(713): Error: no identifier for declarator twoPtrValue
tcl.d(718): Error: no identifier for declarator ptrAndLongRep
tcl.d(719): Error: no identifier for declarator internalRep
December 11, 2013
On Wednesday, 11 December 2013 at 23:27:57 UTC, Gary Willoughby wrote:
> On Wednesday, 11 December 2013 at 23:12:39 UTC, bearophile wrote:
>> Adam D. Ruppe:
>>
>>> Nested structs and unions like in your example are supported in D too, same syntax, same effect.
>>
>> But don't forget to add to use "static struct" instad of "struct".
>>
>> Bye,
>> bearophile
>
> Have you got an example because i always get:
>
> tcl.d(713): Error: no identifier for declarator twoPtrValue
> tcl.d(718): Error: no identifier for declarator ptrAndLongRep
> tcl.d(719): Error: no identifier for declarator internalRep

Like this perhaps:

struct Tcl_Obj
{
    int refCount;
    char* bytes;
    int length;
    Tcl_ObjType* typePtr;

    static union internalRep
	{
		c_long longValue;
		double doubleValue;
		void* otherValuePtr;
		Tcl_WideInt wideValue;

		static struct twoPtrValue
		{
			void* ptr1;
			void* ptr2;
		}

		static struct ptrAndLongRep
		{
			void* ptr;
			c_ulong value;
		}
    }
}
December 11, 2013
Gary Willoughby:

> Have you got an example because i always get:
>
> tcl.d(713): Error: no identifier for declarator twoPtrValue
> tcl.d(718): Error: no identifier for declarator ptrAndLongRep
> tcl.d(719): Error: no identifier for declarator internalRep

In D you can't define a struct/union and use it to define an instance on the fly. You have to split definition and use in two parts.

Bye,
bearophile
December 11, 2013
On Wednesday, 11 December 2013 at 23:35:04 UTC, Gary Willoughby wrote:
>     static union internalRep


try

static union InternalRep { /* note the capital letter */
  /* snip */
}
InternalRep internalRep;; // still need a decl

December 11, 2013
On Wednesday, 11 December 2013 at 23:36:11 UTC, bearophile wrote:
> In D you can't define a struct/union and use it to define an instance on the fly.

Well, you can if it is anonymous.

struct Foo {
    union {
        struct { ubyte a; ubyte b; }
        ubyte[2] arr;
    }
}

That works in D, and it makes foo.a == arr[0] and foo.b == arr[1];
December 11, 2013
Adam D. Ruppe:

> Well, you can if it is anonymous.
>
> struct Foo {
>     union {
>         struct { ubyte a; ubyte b; }
>         ubyte[2] arr;
>     }
> }
>
> That works in D, and it makes foo.a == arr[0] and foo.b == arr[1];

Right :-) I like D structs.

Bye,
bearophile
« First   ‹ Prev
1 2