Structs of arbitrary size?

A

Ann O'Nymous

I think I know the answer to this is "no", but I'll ask anyway.

Is it possible to define a struct of arbitrary size as a parameter to a
routine, with its size passed in as another parameter or parameters?

By this, I mean something like this:

int foo(struct A *ptr; int size1, int offset, int size2) {

where "struct A" is something like this:

struct A {
char field1[offset];
char field2[size2];
char field3[size1-offset-size2];
};

That is, ptr is a pointer to a struct with a size of size1
(it's actually a pointer to an array of these things, so that
ptr++ advances to the next one), it has 3 fields, the first size
"offset", the second size "size2", the third containing the remainder.

In other words, if I do
foo(pointer,20,10,4);

it's as if foo had the lines in it:

struct A {
char field1[10];
char field2[4];
char field3[6]; // 20-10-4 = 6
};

and a ptr++ in foo would advance it by 20.

How about this:

foo(array,w,h) int w,h; char array[w][h]; {
int i,j;
for (i=0; i<w; i++ {
for (j=0; j<h; j++) {
array[j] = blablabla();
}
}

This isn't overly important, as I can do what I really need to do using
pointers to char. Just another "can I do this this way?" question.
 
S

Shao Miller

I think I know the answer to this is "no", but I'll ask anyway.

Is it possible to define a struct of arbitrary size as a parameter to a
routine, with its size passed in as another parameter or parameters?

By this, I mean something like this:

int foo(struct A *ptr; int size1, int offset, int size2) {

where "struct A" is something like this:

struct A {
   char field1[offset];
   char field2[size2];
   char field3[size1-offset-size2];

};

That is, ptr is a pointer to a struct with a size of size1
(it's actually a pointer to an array of these things, so that
ptr++ advances to the next one), it has 3 fields, the first size
"offset", the second size "size2", the third containing the remainder.

In other words, if I do
foo(pointer,20,10,4);

it's as if foo had the lines in it:

struct A {
   char field1[10];
   char field2[4];
   char field3[6];     // 20-10-4 = 6

};

and a ptr++ in foo would advance it by 20.

How about this:

foo(array,w,h) int w,h; char array[w][h]; {
   int i,j;
   for (i=0; i<w; i++ {
     for (j=0; j<h; j++) {
       array[j] = blablabla();
     }
   }

This isn't overly important, as I can do what I really need to do using
pointers to char.  Just another "can I do this this way?" question.


An implementation can put padding between members of a 'struct'. Your
implementation might offer "packed" structures (_Packed or
__attribute__((packed)), as examples). Otherwise, there is no
guarantee that the 'struct' above has a 'sizeof' value of '20'.

Are you asking if you can have a 'struct A' type whose 'sizeof' cannot
be determined at translation-time, but whose size needs to be known at
translation-time for purposes of pointer arithmetic?
 
B

Ben Bacarisse

Ann O'Nymous said:
I think I know the answer to this is "no", but I'll ask anyway.

Is it possible to define a struct of arbitrary size as a parameter to
a routine, with its size passed in as another parameter or parameters?
No.

By this, I mean something like this:

int foo(struct A *ptr; int size1, int offset, int size2) {

where "struct A" is something like this:

struct A {
char field1[offset];
char field2[size2];
char field3[size1-offset-size2];
};

The closest you can come is to have the last member be an array of
unspecified size:

struct A {
int foo;
double bar;
char rest[];
};

but the size of the struct will be reported as if 'rest' were not there.
All it does is formalise the idea that an actual instance of struct A
may be larger than sizeof(struct A) and that the rest of it can be
accessed via the last member. (Look up "struct hack" for more
information.)

This isn't overly important, as I can do what I really need to do
using pointers to char. Just another "can I do this this way?"
question.

Yes, I think pointers and offsets will be the only way to even get
close.
 
B

Ben Pfaff

Ann O'Nymous said:
Is it possible to define a struct of arbitrary size as a parameter to
a routine, with its size passed in as another parameter or parameters?

By this, I mean something like this:

int foo(struct A *ptr; int size1, int offset, int size2) {

where "struct A" is something like this:

struct A {
char field1[offset];
char field2[size2];
char field3[size1-offset-size2];
};

No, but C99 has a similar feature for array parameters, e.g. see
this example from the specification:

20 EXAMPLE 4 The following prototype has a variably modified parameter.
void addscalar(int n, int m, double a[n][n*m+300], double x);
int main()
{
double b[4][308];
addscalar(4, 2, b, 2.17);
return 0;
}
void addscalar(int n, int m, double a[n][n*m+300], double x)
{
for (int i = 0; i < n; i++)
for (int j = 0, k = n*m+300; j < k; j++)
// a is a pointer to a VLA with n*m+300 elements
a[j] += x;
}
 
J

Jean-Christophe

Is it possible to define a struct of arbitrary size as a parameter to a
routine, with its size passed in as another parameter or parameters?

Something like this:

void fct( void *ptr, const unsigned int size );

Function is called this way:
MyStruct A = { /* data */ };
fct( (void*)(&A), sizeof(A) );

It may be interresting to define the first
element of the structure as the struct size :

typedef struct {
unsigned int size;
/* etc */
} MyStruct;

So you can do this :

MyStruct A = { sizeof(MyStruct), ... };

void fct( void *ptr )
{
unsigned int size = *(unsigned int*)(ptr);
/* etc */
}

And do the same for all the different
elements inside your structure.

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top