S
Shao Miller
An interesting fellow in another C-devoted forum brought up a
question:
struct { char x; } f() {
/* ... */
/* What can we return? */
return TODO;
}
He/she suggested that all anonymous (tagless) 'struct's had
incompatible types, which didn't fit my recollection of 6.2.7,p1,
where I remembered "...are compatible if their tags and members
satisfy the following requirements..." However, upon re-reading, that
text is immediately preceded by "...declared in separate translation
units".
It also appears to be related to the common situation in Annex I,p2,
first sub-point.
So the best I could muster up were these:
-----
struct { char x; } f() {
/* ... */
/* Well actually, we won't return. */
return f();
}
/* main() */
-----
-----
/**
* This code is non-portable due to:
* - Pointer arith. with a null pointer
* - Casting a pointer to size_t to yield
* a simple "byte address" integer
* - The assumption that "byte address 0" is
* suitably aligned for any type
* Furthermore, the function returns a _pointer_, unlike the original.
*/
#include <stddef.h>
#include <stdio.h>
#define TT (1 ? 0 : f())
#define sz (sizeof *f())
struct { char x; } *f(void) {
unsigned char scratch[sz * 2];
size_t off = (size_t)&scratch;
off += sz - off % sz;
off /= sz;
TT[off].x = 'C';
return TT + off;
}
int main(void) {
char c;
c = f()[0].x;
printf("Returned: '%c'\n", c);
return 0;
}
-----
-----
/**
* This code should be fine (right?) except, as was pointed
* out by the original questioner, that it's not thread-safe.
* The function also returns a _pointer_, unlike the original.
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
struct { char x; } *f(void) {
static void *scratch = NULL;
static int called_by_self = 0;
if (called_by_self)
return scratch;
if (!scratch)
scratch = malloc(sizeof *f());
if (!scratch)
return NULL;
called_by_self = 1;
f()->x = 'C';
called_by_self = 0;
return scratch;
}
int main(void) {
char c;
/* We should watch-out for a null pointer here, in practice. */
c = f()->x;
printf("Returned: '%c'\n", c);
return 0;
}
-----
Does anyone have any other ideas for how the function 'f' of the
original question might be able to return a value?
Thanks.
- Shao Miller
question:
struct { char x; } f() {
/* ... */
/* What can we return? */
return TODO;
}
He/she suggested that all anonymous (tagless) 'struct's had
incompatible types, which didn't fit my recollection of 6.2.7,p1,
where I remembered "...are compatible if their tags and members
satisfy the following requirements..." However, upon re-reading, that
text is immediately preceded by "...declared in separate translation
units".
It also appears to be related to the common situation in Annex I,p2,
first sub-point.
So the best I could muster up were these:
-----
struct { char x; } f() {
/* ... */
/* Well actually, we won't return. */
return f();
}
/* main() */
-----
-----
/**
* This code is non-portable due to:
* - Pointer arith. with a null pointer
* - Casting a pointer to size_t to yield
* a simple "byte address" integer
* - The assumption that "byte address 0" is
* suitably aligned for any type
* Furthermore, the function returns a _pointer_, unlike the original.
*/
#include <stddef.h>
#include <stdio.h>
#define TT (1 ? 0 : f())
#define sz (sizeof *f())
struct { char x; } *f(void) {
unsigned char scratch[sz * 2];
size_t off = (size_t)&scratch;
off += sz - off % sz;
off /= sz;
TT[off].x = 'C';
return TT + off;
}
int main(void) {
char c;
c = f()[0].x;
printf("Returned: '%c'\n", c);
return 0;
}
-----
-----
/**
* This code should be fine (right?) except, as was pointed
* out by the original questioner, that it's not thread-safe.
* The function also returns a _pointer_, unlike the original.
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
struct { char x; } *f(void) {
static void *scratch = NULL;
static int called_by_self = 0;
if (called_by_self)
return scratch;
if (!scratch)
scratch = malloc(sizeof *f());
if (!scratch)
return NULL;
called_by_self = 1;
f()->x = 'C';
called_by_self = 0;
return scratch;
}
int main(void) {
char c;
/* We should watch-out for a null pointer here, in practice. */
c = f()->x;
printf("Returned: '%c'\n", c);
return 0;
}
-----
Does anyone have any other ideas for how the function 'f' of the
original question might be able to return a value?
Thanks.
- Shao Miller