Help me spot a problem

Mark Anthony BROWN dougl at students.cs.mu.oz.au
Fri Mar 14 18:15:59 AEDT 1997


Hello,

Mercury's runtime system is catching seg-faults in some code of mine,
but I can't see why.  I am trying to write some predicates that achieve
polymorphism by taking closures in an argument.

Here's my attempt at a simple case.  To use the predicate pwrite/4, you
must pass it a closure that has the appropriate type and mode for
printing the other argument.

%%%%%%%%%%%%%%

:- module printable.
:- interface.
:- import_module io.

:- type printable(T) ---> class(pred(T, io:state, io:state)).
:- inst printable_data = bound(class(pred(in, di, uo) is det)).
:- mode printable :: in(printable_data).
:- mode new_printable :: out(printable_data).

:- pred pwrite(printable(T)::printable, T::in, io:state::di, io:state::uo) is det.

:- implementation.

pwrite(C, Data) -->
        call(Write, Data),
        { C = class(Write) }.

:- end_module printable.

%%%%%%%%%%%%%%%

% The above module can be used as follows:

:- module test_printable.
:- interface.

:- import_module printable, io.

:- pred main(io:state, io:state).
:- mode main(di, uo) is det.

	% This is how we can make a concrete type.
:- func integer = printable(int).
:- mode integer = new_printable is det.

:- implementation.

	% This constant function can be used to supply pwrite/4
	% Note that by using write_int/4, the compiler will ensure
	% that the other argument to pwrite is in fact an int.
integer = class(write_int).

	% Real-code usage is now nice and simple
main -->
        pwrite(integer, 99).

%%%%%%%%%%%%%%%%

These two modules compile without a problem, and produce the following when run:

*** Mercury runtime: caught segmentation violation ***
cause: address not mapped to object
PC at signal: 4396972367248 (3ffbff9dd90)
address involved: 63
You can get a stack dump by using grade debug
exiting from signal handler


Note:  63 is 99 in hexadecimal; if I change the integer, the violation 
moves correspondingly.

Can anybody see the problem?  Does it belong to any of these categories:
    - compiler bug (eg reporting that program as type-correct when it
      isn't)
    - implementation (eg have I relied on an aspect of call/N that is
      not yet implemented?)
    - a mistake, misconception or oversight of mine

Thanks for any advice,
Mark.

P.S.  I have other similar examples that _do_ work.  The big difference in
this case is that this example passes io:write_string, which uses unique
modes and DCGs.
P.P.S.  Is there more obvious way of doing all this?




More information about the users mailing list