S
Shao Miller
Good day, folks. I'm pondering 'offsetof()'. 6.6 "Constant
expressions" might be relevant.
Suppose we've:
int helper[2];
enum foo {
bar = helper + 1 - helper
};
int main(void) {
return 0;
}
Does that code include any undefined behaviour?
How about in:
int (* helper)[2];
enum foo {
bar = *helper + 1 - *helper
};
int main(void) {
return 0;
}
Is there undefined behaviour there? Note that '*helper' is an array
which "decays" to a pointer to the first element. Also note that
'helper' is a pointer to 'int[2]'. But does it matter what the stored
value of 'helper' is or is the value of 'bar' independent of it?
So let's please go on to:
char ** helper;
enum foo {
bar = *helper + 1 - *helper
};
int main(void) {
return 0;
}
Is there undefined behaviour there? So what about in:
char ** helper;
struct s {
int arr[2];
};
enum foo {
bar = ((struct s *)*helper)->arr + 1 - ((struct s *)*helper)->arr
};
int main(void) {
return 0;
}
? And then:
char ** helper;
struct s {
int x;
short y;
int z;
};
enum foo {
bar = (char *)&((struct s *)*helper)->z -
(char *)((struct s *)*helper)
};
int main(void) {
return 0;
}
In the example just above, does the value of 'bar' depend on the value
of 'helper'? Is 'helper' evaluated? If so, what if we use that mess as
part of a type-name in an operand to 'sizeof', as in:
char ** helper;
struct s {
int x;
short y;
int z;
};
enum foo {
bar = sizeof (char[
(char *)&((struct s *)*helper)->z -
(char *)((struct s *)*helper)
])
};
int main(void) {
return 0;
}
Could 'offsetof' be reasonably portable as:
char ** helper;
#define DUMMY_OF(type) ((type *)*helper)
#define ADDRESS_AT(address) ((char *)(address))
#define DUMMY_MEMBER_ADDRESS(type, member) (&DUMMY_OF(type)->member)
#define PROTECT(expression) (sizeof (char[(expression)]))
#define OFFSETOF(type, member) (PROTECT( \
ADDRESS_AT(DUMMY_MEMBER_ADDRESS(type, member)) - \
ADDRESS_AT(DUMMY_OF(type)) \
))
struct s {
int x;
short y;
int z;
};
enum foo {
bar = OFFSETOF(struct s, z)
};
int main(void) {
return 0;
}
Are there any null pointers or other dragons in there?
Thanks for any insight you can provide!
expressions" might be relevant.
Suppose we've:
int helper[2];
enum foo {
bar = helper + 1 - helper
};
int main(void) {
return 0;
}
Does that code include any undefined behaviour?
How about in:
int (* helper)[2];
enum foo {
bar = *helper + 1 - *helper
};
int main(void) {
return 0;
}
Is there undefined behaviour there? Note that '*helper' is an array
which "decays" to a pointer to the first element. Also note that
'helper' is a pointer to 'int[2]'. But does it matter what the stored
value of 'helper' is or is the value of 'bar' independent of it?
So let's please go on to:
char ** helper;
enum foo {
bar = *helper + 1 - *helper
};
int main(void) {
return 0;
}
Is there undefined behaviour there? So what about in:
char ** helper;
struct s {
int arr[2];
};
enum foo {
bar = ((struct s *)*helper)->arr + 1 - ((struct s *)*helper)->arr
};
int main(void) {
return 0;
}
? And then:
char ** helper;
struct s {
int x;
short y;
int z;
};
enum foo {
bar = (char *)&((struct s *)*helper)->z -
(char *)((struct s *)*helper)
};
int main(void) {
return 0;
}
In the example just above, does the value of 'bar' depend on the value
of 'helper'? Is 'helper' evaluated? If so, what if we use that mess as
part of a type-name in an operand to 'sizeof', as in:
char ** helper;
struct s {
int x;
short y;
int z;
};
enum foo {
bar = sizeof (char[
(char *)&((struct s *)*helper)->z -
(char *)((struct s *)*helper)
])
};
int main(void) {
return 0;
}
Could 'offsetof' be reasonably portable as:
char ** helper;
#define DUMMY_OF(type) ((type *)*helper)
#define ADDRESS_AT(address) ((char *)(address))
#define DUMMY_MEMBER_ADDRESS(type, member) (&DUMMY_OF(type)->member)
#define PROTECT(expression) (sizeof (char[(expression)]))
#define OFFSETOF(type, member) (PROTECT( \
ADDRESS_AT(DUMMY_MEMBER_ADDRESS(type, member)) - \
ADDRESS_AT(DUMMY_OF(type)) \
))
struct s {
int x;
short y;
int z;
};
enum foo {
bar = OFFSETOF(struct s, z)
};
int main(void) {
return 0;
}
Are there any null pointers or other dragons in there?
Thanks for any insight you can provide!