2
votes

I'm tryin to implement a protected object in Ada which has a reference to a procedure it owns. This is my code:

procedure sm is

    type StateHandler is access procedure;

    protected Motor is

    private
        procedure proc;

        x : StateHandler := proc'Access;

    end Motor;

    protected body Motor is
        procedure proc is
        begin
            Put_Line("HELLO WORLD");
        end proc;
    end Motor;


begin
    Put_Line("ASD");
end sm;

I have tried Motor.proc'Access as well.

When I try to compile this code, I obtain the following errors:

sm.adb:18:29: subprogram "proc" has wrong convention
sm.adb:18:29: does not match "StateHandler" declared at line 11
sm.adb:18:29: probable missing pragma Convention for "StateHandler"
gnatmake: "sm.adb" compilation error
Makefile:3: recipe for target 'ADA' failed
make: *** [ADA] Error 4

I have tried many ways to solve it but I am unable.

1
Interesting one! "pragma convention" controls things such as the calling convention of a procedure, so if you're interfacing to another language, you might add pragma Convention (C, proc); afher the declaration of proc. It makes sense that protected procedures will have different calling conventions from normal ones, and accessing a protected procedure via a non-protected (so to speak) access type may be problematic ... but that's as far as I can get, offhand. - user_1818839

1 Answers

6
votes

Interesting one!

"pragma convention" controls things such as the calling convention of a procedure, so if you're interfacing to another language, you might add pragma Convention (C, proc); after the declaration of proc. That tells the compiler to set up the stack frame and parameters to call a procedure (void function) written in C. It makes sense that protected procedures will have different calling conventions from normal ones, and accessing a protected procedure via a non-protected (so to speak) access type may be problematic ... but that's as far as I got offhand.

I think you need to read this page of the Annotated ARM ... "For example, setting the Convention of a protected procedure to Ada is probably wrong. Rather than enumerating all such cases, however, we leave it up to implementations to decide what is sensible. "

Different CPUs have different requirements for guards, locks and atomic operations, so this permits Ada implementations to allow the same convention (and bypass this problem) for targets where it makes sense.

That page links to AARM chapter 6.3.1 where we see "The default calling convention is protected for a protected subprogram, and for an access-to-subprogram type with the reserved word protected in its definition." as opposed to conventions Ada, or Intrinsic (or C or Fortran). Nicely thorough of the writers to cover the "access to procedure" issue here.

And bingo ...

type StateHandler is access protected procedure;

This restricts StateHandler to point to procedures with the correct calling conventions for protected procedures, such as 'proc' in this example.

The error message was not especially helpful, unless you had already dealt with pragma convention in other contexts, which gave me enough breadcrumbs to follow.