Chris said:
#include <stdio.h>
struct S { char a[1]; };
int main(void) {
struct T { struct S { char a[1000]; } a; };
printf("sizeof(struct S) = %lu\n", (unsigned long)sizeof(struct S));
return 0;
}
(Exercise: what is the most likely output of the above, as both
C and C++? Why is it different?)
1000 using C, and 1 using C++. My money is on scope-resolution
differences between the languages. Please correct me if I am wrong.
Got it in one. Of course, neither 1 nor 1000 are guaranteed
(because the structures may include padding), but they are at
least extremely likely to be different.
... There are machines on which [(*f)(), where f==NULL,] turns
out to be a recursive call to main().
I really didn't know that, thank you.
I saw in another thread that you were wondering where this was the
case. The case I was thinking of in particular occurred on the
VAX running 4.xBSD, but it could occur on any similar machine.
The most basic requirement is that the NULL function pointer must
point to executable code. This was true since NULL on that machine
was 32-zero-bits, and 4BSD had the program starting on page zero
(VMS, by contrast, made page-zero off limits by default, so that
*(char *)0 got a runtime fault, and attempts to call through NULL
also faulted).
The second tricky bit was that location 0 began with a 16-bit
register mask, even though the kernel launched executables by
pointing the program counter to the startup code rather than
executing the VAX's normal subroutine-call instruction, "CALLS".
(The startup code was thus at address 2. As I recall, 0x00 is a
VAX "HALT" instruction, so the two zero bytes at location zero
would have caused trouble if the binary were launched at address
0. However, having the register-save-mask there enables one to
use the VAX's CALLS instruction.)
The final tricky bit was that this recursive call to main()
would only work if the registers were set up properly. I have
forgotten what the register setup was supposed to be, and just
how tolerant this all was (whether by design or coincidence).
I do, however, remember having one program blow up with a stack
overflow, and in the debugger, seeing a seemingly-infinite
sequence of calls starting with the startup code calling main()
which called some functions which eventually called through the
NULL function-pointer which called main(), etc.
One could get the same effect on other machines, for the same
reasons.