What is the 'Address of an Ada subprogram passed as an access parameter? -
compiling following program without optimization, , running it, see program_error
,
raised program_error : addreq.adb:16 explicit raise
or, updating in view of simon wright's answer,
raised program_error : using address
this happens when using gnat gpl 2014 on either mac os x or on gnu/linux x84_64, on linux, strangely, program. other versions of gnat produce code doesn't raise, older compilers not accept (access-to-function parameters being more recent, i'm not surprised). since program needs identify addresses of subprograms, hoping definitive statement in rm; 13.3 (11) has ramifications grow waivers, iinm. so, referring program below, would
yes_no.all'address = no'adress
be true statement if interpreted lrm? legit? yes_no.all
proper way refer function no
(if taking 'address
)? there indirection through different pointer types, 1 having deeper accessibility, change picture? thinking yes_no.all
should yield same 'address
no
, apparently not, compilers.
with system; procedure addreq function no (ignored : integer) return boolean begin return false; end no; procedure taking (yes_no : access function (n : integer) return boolean) use type system.address; begin if yes_no.all'address /= no'address raise program_error; end if; end taking; begin taking (no'access); end addreq;
one more update: if make addreq
package , have subprogram call taking
, thus
with addreq; -- package procedure driver use addreq; begin taking (no'access); end driver;
then no exception raised.
if yes_no.all'address
not equal no'address
, yes_no.all'address
address of kind of wrapper code.
no
function nested inside procedure. if no'access
, compiler cannot create one-word pointer value address of no
. reason when code makes indirect call through access value, code has special no
can access local variables belonging addreq
, somewhere on stack. example, 1 way provide access pass static link parameter no
; pointer points addreq
's stack frame, contain local variables (or along lines). thus, when indirect call made through access, caller has know static link is. 1 solution make nested access-to-function types dope vectors, contain function address , static link. generate wrapper code. wrapper code responsible calling called subprogram static link parameter, , access value one-word pointer, address of wrapper code. believe gnat takes approach. advantage makes possible pass my_function'access
parameter c function, use callback. when c code calls through function pointer, calls wrapper function calls nested function correct static link. there significant amount of public ada code depends on mechanism. (gtkada relies heavily on it.)
however, if access value points wrapper, instead of actual function, the_access.all'address
won't return think should. when code executes the_access.all'address
, if the_access
single word address in it, that's attribute can return--the address in pointer.
more: don't know whether original code part of larger example or test see compiler does. comparing 'address
values see if subprogram-access parameter refers specific subprogram strikes me poor design, , comparing 'access
no better. avoid doing in c. there's more object-oriented solution problem (note can use tagged types cause indirect subprogram calls take place, because tagged type operations dispatching). e.g.
type boolean_function_object abstract tagged null record; function apply (obj : boolean_function_object; n : integer) return boolean; function is_constant_false (obj : boolean_function_object) return boolean; type no_function new boolean_function_object null record; overriding function apply (obj : no_function; n : integer) return boolean (false); overriding function is_constant_false (obj : no_function) return boolean (true); procedure taking (func : boolean_function_object) begin if not func.is_constant_false raise program_error; end if; end taking;
might not best design in cases, should considered if there seems need check subprogram address particular subprogram. 1 thing, more flexible; programmer can define derived type apply
return false
else, such writing argument log file.
Comments
Post a Comment