J
James Harris
Some observations on C compiler calling mechanisms and structure
literals.
No need to reply. I am looking at inter-language working so this is
not necessarily about standard C but these are some notes of findings
while looking at ways gcc compiled specific constructs. Might be of
interest to some others. All errors below mine and not gcc's!
Target Routine
==============
The normal func(...) compiled, as expected, to the x86 assembly code
call func
The indirect (*func_p)(...) compiled to
call [func_p]
I.e. an indirect call where the address of func is stored in func_p.
Interestingly as long as func_p was declared as int (*func_p)(...)
even the bare call to func_p(...) (without the parens around the
function name in the call) compiled to the indirect
call [func_p]
So where an indirect call to a function was wanted the memory cell
holding the address of the function had to be declared as such. When
that cell was 'called' the compiler generated an indirect call to the
referent. That was a surprise, but a pleasant one. It means I only
need to declare a pointer as pointing to a function for that function
to be called through the pointer and I can stick with the familiar and
normal call syntax. Not sure if it is standard that C work this way.
Parameters
=========
Given
struct pblock_func {
int fd;
int mlen;
} pb1;
void (*func_p)(struct pblock_func *);
a call func_p(&pb1) compiled to
push pb1 ;i.e. the address of pb1
call [func_p]
In other words the parameter block is a structure in memory and the
stack holds a pointer to it. Even given this mechanism the stack can
hold both the parameter block and the address of it with
func_p(&(struct pblock_func){4, 11});
Being previously unaware of struct literals the ability to code this
was another surprise! Again, a good surprise, though it looks a bit
odd.
One More
========
I found that later unspecified elements of the anonymous parameter
block were implicitly zeroed so in
struct x {
int arg;
int result;
};
func_p(&(struct x){6});
Only the arg was specified (not the result) but gcc zeroed the missing
component of the anonymous struct.
James
literals.
No need to reply. I am looking at inter-language working so this is
not necessarily about standard C but these are some notes of findings
while looking at ways gcc compiled specific constructs. Might be of
interest to some others. All errors below mine and not gcc's!
Target Routine
==============
The normal func(...) compiled, as expected, to the x86 assembly code
call func
The indirect (*func_p)(...) compiled to
call [func_p]
I.e. an indirect call where the address of func is stored in func_p.
Interestingly as long as func_p was declared as int (*func_p)(...)
even the bare call to func_p(...) (without the parens around the
function name in the call) compiled to the indirect
call [func_p]
So where an indirect call to a function was wanted the memory cell
holding the address of the function had to be declared as such. When
that cell was 'called' the compiler generated an indirect call to the
referent. That was a surprise, but a pleasant one. It means I only
need to declare a pointer as pointing to a function for that function
to be called through the pointer and I can stick with the familiar and
normal call syntax. Not sure if it is standard that C work this way.
Parameters
=========
Given
struct pblock_func {
int fd;
int mlen;
} pb1;
void (*func_p)(struct pblock_func *);
a call func_p(&pb1) compiled to
push pb1 ;i.e. the address of pb1
call [func_p]
In other words the parameter block is a structure in memory and the
stack holds a pointer to it. Even given this mechanism the stack can
hold both the parameter block and the address of it with
func_p(&(struct pblock_func){4, 11});
Being previously unaware of struct literals the ability to code this
was another surprise! Again, a good surprise, though it looks a bit
odd.
One More
========
I found that later unspecified elements of the anonymous parameter
block were implicitly zeroed so in
struct x {
int arg;
int result;
};
func_p(&(struct x){6});
Only the arg was specified (not the result) but gcc zeroed the missing
component of the anonymous struct.
James