typedef struct {
char a[100];
char const *secondHalfOfA;
}
//Can i set { secondHalfOfA = a[49]; } somehow?
4 Answers
Sure you can.
typedef struct {
char a[100];
char const *const secondHalfOfA;
} toto;
#define TOTO_INITIALIZER(NAME) { .secondHalfOfA = &((NAME).a[49]) }
static toto A = TOTO_INITIALIZER(A);
Using initializers like that consistently has the extra plus that it initializes your array with all 0, too.
This is for C99 with designated initializers. If you only have historical C you could do something like
#define TOTO_INITIALIZER(NAME) { { 0 }, &((NAME).a[49]) }
Edit: Seeing your comment on another answer, I suppose that you had the const in your type on the wrong side. But real C initialization works very well for that case, too.
Comments
You cannot automatically initialize a pointer to the middle of an object.
You can, however, pretend to have overlapping objects. It's not pretty though :-)
#include <stdio.h>
#include <string.h>
struct twoparts {
union {
char a[20];
struct {
char dummy[10];
char b[10];
} s;
} u;
};
int main(void) {
struct twoparts x;
strcpy(x.u.a, "1234567890123456789");
printf("second part: %s\n", x.u.s.b);
return 0;
}
2 Comments
#define secondHalfOfA(s) ((s).a + 49), then use secondHalfOfA(A) instead of A.secondHalfOfA.Is Pablo said, you can't do that with an initializer. You can do it easily enough after initialization, but it has to be every time:
// Definition (once)
typedef struct {
char a[100];
char const *secondHalfOfA;
} TYPENAME;
// Use (each time)
TYPENAME t;
t.secondHalfOfA = &t.a[49];
// Or
TYPENAME *pt;
pt = malloc(sizeof(*pt));
pt->secondHalfOfA = &pt->a[49];
It's for reasons like this that we have object oriented languages like C++ (and Java and ...) and their associated constructors, so that we can create structures with custom initializations reliably.
Demonstration program:
#include <stdio.h>
// Definition (once)
typedef struct {
char a[100];
char const *secondHalfOfA;
} TYPENAME;
int main(int argc, char* argv[])
{
// Use of the type (need to initialize it each time)
TYPENAME t;
t.secondHalfOfA = &t.a[49];
// Example actual use of the array
t.a[49] = 'A';
printf("%c\n", *t.secondHalfOfA); // Prints A
// Uncommenting the below causes a compiler error:
// "error: assignment of read-only location ‘*t.secondHalfOfA’"
// (That's gcc's wording; your compiler will say something similar)
//*t.secondHalfOfA = 'B';
//printf("%c\n", *t.secondHalfOfA);
return 0;
}
Compilation and output using gcc:
$ gcc -Wall temp.c $ ./a.out A
3 Comments
char const * is a pointer to static data, not a static pointer. The above is fine, as long as you don't try to write a character via the secondHalfOfA pointer. I've added a sample program showing the difference.char * const (I had to remind myself). More here: stackoverflow.com/questions/1658977/…