The meaning of postcondition - ada

I can understand the meaning and purpose of preconditions in this code but I have a problem in understanding the meaning and purpose of the postconditions. In Push I know that this part to increase pointer after pushing integer ( Pointer = Pointer~ +1 ). In Pop I understand this part to decrease pointer after popping integer (Pointer=Pointer~ - 1).
package Stack
--# own S, Pointer;
--# initializes S, Pointer;
with SPARK_Mode
is
pragma Elaborate_Body(Stack);
Stack_Size : constant := 100;
subtype Pointer_Range is Integer range 0 .. Stack_Size;
subtype Index_Range is Pointer_Range range 1..Stack_Size;
type Vector is array(Index_Range) of Integer;
S : Vector;
Pointer : Pointer_Range;
function isEmpty return Boolean;
--# global in Pointer;
procedure Push(X : in Integer);
--# global in out S, Pointer;
--# derives S from S, Pointer, X &
--# Pointer from Pointer;
procedure Pop(X : out Integer);
--# global in S; in out Pointer;
--# derives Pointer from Pointer &
--# X from S, Pointer;
procedure Peek(X : out Integer);
--# global in S, Pointer;
--# derives X from S, Pointer;
procedure Swap(OldLoc, NewLoc: in Pointer_Range);
--# global in out S;
--# in Pointer;
--# derives S from S, OldLoc, NewLoc, Pointer ;
end Stack;

In general, a post-condition presents the promises from the implementor to the user of how the state of (a subset of) the system will be after a to the subprogram in question.
The specific post-conditions here seem to explain how the stack is implemented.

With postconditions, you have to define the new state in terms of the effect the subprogram should have had on the old state.
When the postcondition says post Pointer = Pointer~ +1, it means that the new value of Pointer should be the old value + 1; i.e. Variable~ means "the value of Variable on entry to the subprogram".
I’m afraid I don’t know what S~[Pointer=>X] means; perhaps "the Pointerth element of S is now X" (what about specifying that all the other elements of S are to be unchanged?).
A couple of points:
This is an unusual mixture of SPARK2014 notation (with SPARK_Mode;) and old-style annotations (--#). I wondered whether the new SPARK software (gnatprove) needs the first in order to recognise the second, but it looks more like this is an intermediate stage in a conversion from old to new.
Pointer is a silly name for something that is clearly an array index. Perhaps Top would be less misleading.

Yet another high-level interpretation: preconditions are requirements to let the caller in, postconditions are checks on what happened inside

Related

Deallocating arrays defined from c_f_pointer

The following code compiles in both GNU gfortran and Intel ifort. But only the gfortran compiled version will run successfully.
program fort_tst
use iso_c_binding
INTEGER, POINTER :: a(:)
TYPE(C_PTR) :: ptr
INTEGER, POINTER :: b(:)
ALLOCATE(a(5))
ptr = c_loc(a)
CALL c_f_pointer(ptr,b,[5])
DEALLOCATE(b)
end program fort_tst
The error in the Intel compiled code is :
forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated
Image PC Routine Line Source
fort_tst 000000000040C5A1 Unknown Unknown Unknown
fort_tst 0000000000403A17 Unknown Unknown Unknown
fort_tst 0000000000403812 Unknown Unknown Unknown
libc-2.17.so 00002AAAAB20F555 __libc_start_main Unknown Unknown
fort_tst 0000000000403729 Unknown Unknown Unknown
The gfortran code runs to completion. A quick valgrind check does not find any leaks.
Can someone confirm whether the code above is valid/legal code?
I am running
ifort (IFORT) 2021.2.0 20210228
and
GNU Fortran (GCC) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
UPDATE :
What is interesting is that gfortran does the right thing, (i.e. deallocates only allocated memory), even when the user tries to confound it with improper index remapping, or a bogus shape argument. So the internal array descriptor is being properly copied over with gfortran's c_f_pointer.
The error is issued, because the compiler claims that the pointer that is being allocated was not allocated by an allocate statement.
The rules are (F2018):
9.7.3.3 Deallocation of pointer targets
1 If a pointer appears in a DEALLOCATE statement, its association status shall be defined.
Deallocating a pointer that is disassociated or whose target was not
created by an ALLOCATE statement causes an error condition in the
DEALLOCATE statement. If a pointer is associated with an allocatable
entity, the pointer shall not be deallocated. A pointer shall not be
deallocated if its target or any subobject thereof is argument
associated with a dummy argument or construct associated with an
associate name.
Your pointer b was associated using the c_f_pointer subroutine. The error condition mentioned is the
forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated
Now we have to be careful, the exact wording is
or whose target was not created by an ALLOCATE statement
The target arguably was created by an allocatable statement. And then went through this indirect chain of association. I am not such an expert language lawyer to be sure whether this makes the target to be applicable or not, when it passed through c_loc() and c_f_pointer().
Gfortran does not issue this error condition and then it works fine because at the end of the day, under the hood, what matters is that the address passed to the system free() function was allocated by the matching system malloc() function.
I think we can conclude that one of the compilers is wrong here, because the mention of the error condition is clear in the standard and either it should be issued or it should not. A third option, that gfortran just leaves it too work, should not happen. Either it is allowed, or an error condition shall be issued.
Re UPDATE: What gfortran does is really sending the address to free(). As long as the pointer is contiguous and starts at the first element, it will work in practice. The size is not necessary and is not passed to free(). The system allocator malloc()/free() stores the size of each allocated system in its own database.
There are even worse abuse cases that can happen and will work just by chance due to this, even if completely illegal in Fortran.
See this:
use iso_c_binding
character, allocatable, target :: a
type(c_ptr) :: p
real, pointer :: b(:)
allocate(a)
p = c_loc(a)
call c_f_pointer(p, b, [1000])
deallocate(b)
end
gfortran is arguably missing a diagnostics opportunity when it comes to the DEALLOCATE statement. ifort is arguably too conservative when it comes to the DEALLOCATE statement.
The error message from ifort is an explicit design choice prohibiting the pointer from C_F_POINTER appearing in a DEALLOCATE statement:
Since the resulting data pointer fptr could point to a target that was not allocated with an ALLOCATE statement, fptr cannot be freed with a DEALLOCATE statement.
There seems little in Fortran 2018 explicitly to support that restriction (even in the case where the target was created by an ALLOCATE statement), and ifort itself isn't consistent in applying it:
use iso_c_binding
integer, pointer :: a, b
type(c_ptr) :: ptr
allocate(a)
ptr = c_loc(a)
call c_f_pointer(ptr,b)
deallocate(b)
end program
However, consider the case
use iso_c_binding
integer, pointer, dimension(:) :: a, b
type(c_ptr) :: ptr
allocate(a(5))
ptr = c_loc(a)
call c_f_pointer(ptr,b,[4])
deallocate(b)
end program
One would surely expect deallocation here to be problematic but this doesn't cause an error condition with gfortran: gfortran isn't carefully checking whether the target is deallocatable (note that it doesn't have to).
There is some subtlety in Fortran 2018's wording of C_F_POINTER (F2018 18.2.3.3)
If both X and FPTR are arrays, SHAPE shall specify a size that is less than or equal to the size of X, and FPTR becomes associated with the first PRODUCT (SHAPE) elements of X (this could be the entirety of X).
and whether "the entirety" of a forms a valid thing to deallocate but ifort's documentation is seemingly too strict and gfortran's checking is not going to catch all invalid cases. There is a case for talking to the vendor of each compiler.
That said, the use of a C_F_POINTER's pointer in a DEALLOCATE statement clearly is more prone to error than "simpler" pointers, and these errors are not ones where we can rely on a compiler to point them out. Even with a conclusion of "clearly this is allowed" I personally would recommend that one avoids this approach where possible without other bad things.
Usage of c_f_pointer is pretty standard behavior in case a Fortran derived type is to be passed to a C++ class as an opaque pointer type, see e.g. the following interoperable class:
module mytype_m
use iso_c_binding
implicit none
private
type, public :: mytype
real, allocatable :: data(:)
contains
procedure :: destroy
procedure :: init
procedure :: printout
end type mytype
public :: mytype_print_c
public :: mytype_init_c
public :: mytype_destroy_c
contains
subroutine init(this,data)
class(mytype), intent(inout), target :: this
real, intent(in) :: data(:)
call destroy(this)
this%data = data
end subroutine init
elemental subroutine destroy(this)
class(mytype), intent(inout), target :: this
integer :: ierr
deallocate(this%data,stat=ierr)
end subroutine destroy
subroutine printout(this)
class(mytype), intent(inout), target :: this
integer :: ndata,i
ndata = merge(size(this%data),0,allocated(this%data))
write(*,1) ndata,(this%data(i),i=1,ndata)
1 format('mytype object has data(',i0,')',:,' = ',*(f3.1,:,', '))
end subroutine printout
subroutine mytype_print_c(this) bind(C,name='mytype_print_c')
type(c_ptr), intent(inout) :: this
type(mytype), pointer :: fortranclass
call c_f_pointer(this, fortranclass)
call fortranclass%printout()
end subroutine mytype_print_c
subroutine mytype_destroy_c(this) bind(C,name='mytype_destroy_c')
type(c_ptr), intent(inout) :: this
type(mytype), pointer :: fortranclass
call c_f_pointer(this, fortranclass)
if (associated(fortranclass)) then
call fortranclass%destroy()
deallocate(fortranclass)
end if
! Nullify C pointer
this = c_null_ptr
end subroutine mytype_destroy_c
subroutine mytype_init_c(this,ndata,data) bind(C,name='mytype_init_c')
type(c_ptr), intent(inout) :: this
integer(c_int), intent(in), value :: ndata
real(c_float), intent(in) :: data(ndata)
type(mytype), pointer :: fortranclass
integer :: ierr
! In case it was previously allocated
call c_f_pointer(this, fortranclass)
allocate(fortranclass,stat=ierr)
call fortranclass%init(data)
this = c_loc(fortranclass)
end subroutine mytype_init_c
end module mytype_m
that would be bound to an opaque pointer in c++:
#include <iostream>
#include <vector>
using namespace std;
// Fortran interoperability
typedef void* mytype;
extern "C" { void mytype_print_c(mytype self);
void mytype_destroy_c(mytype self);
void mytype_init_c(mytype self, const int ndata, float *data); }
// Class definition
class mytype_cpp
{
public:
mytype_cpp(std::vector<float> data) { mytype_init_c(this,data.size(),data.data()); };
~mytype_cpp() { mytype_destroy_c(this); };
void printout() { mytype_print_c(this); };
};
int main()
{
// Print 8--size
std::vector<float> data {1.,2.,3.,4.,5.,6.,7.,8.};
mytype_cpp obj(data); obj.printout();
return 0;
}
which, with gfortran-10, returns
mytype object has data(8) = 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0
I don't have a chance to test with ifort, but it works seamlessly with gcc, how can this approach not be Fortran standard-compliant?
Posts above inspired the following solution. The idea is to create a type that wraps the actual data array. Then, c_loc/c_f_pointer sequence works fine with a pointer to a scalar object. The data array stored in the type can be safely allocated, along with the array type itself.
MODULE arraytype_m
TYPE, PUBLIC :: arraytype
INTEGER, ALLOCATABLE :: data(:)
END TYPE arraytype
END MODULE arraytype_m
PROGRAM fort_tst
USE iso_c_binding
USE arraytype_m
TYPE(arraytype), POINTER :: a, b
TYPE(C_PTR) :: ptr
ALLOCATE(a)
ALLOCATE(a%data(5))
!! Set to C-style pointer, and then copy back to Fortran pointer.
ptr = c_loc(a)
CALL c_f_pointer(ptr,b)
DEALLOCATE(b%data)
DEALLOCATE(b)
END PROGRAM fort_tst
This works with both Intel and gfortan, and is really a better solution than what I was trying to do.
Special thanks for #Federico for posting the C++/Fortran code that made this solution obvious.
Update : A complete code, which shows how the ptr above can be stored in C.
// C code
typedef void* arraytype;
void allocate_array(arraytype *ptr);
void deallocate_array(arraytype *ptr);
void do_something(arraytype *ptr);
int main()
{
arraytype ptr;
allocate_array(&ptr);
do_something(&ptr);
deallocate_array(&ptr);
return 0;
}
and the corresponding Fortran :
!! Fortran code
MODULE arraytype_mod
TYPE, PUBLIC :: arraytype
DOUBLE PRECISION, POINTER :: data(:)
END TYPE arraytype
END MODULE arraytype_mod
SUBROUTINE allocate_array(ptr) BIND(C,name='allocate_array')
USE iso_c_binding
USE arraytype_mod
TYPE(c_ptr) :: ptr
TYPE(arraytype), POINTER :: a
ALLOCATE(a)
ALLOCATE(a%data(5))
ptr = c_loc(a)
END
SUBROUTINE deallocate_array(ptr) BIND(C,name='deallocate_array')
USE iso_c_binding
USE arraytype_mod
TYPE(C_PTR) :: ptr
TYPE(arraytype), pointer :: a
CALL c_f_pointer(ptr,a)
DEALLOCATE(a%data)
DEALLOCATE(a)
END
SUBROUTINE do_something(ptr) BIND(C,name='do_something')
USE iso_c_binding
USE arraytype_mod
TYPE(c_ptr) :: ptr
TYPE(arraytype), POINTER :: a
CALL c_f_pointer(ptr,a)
a%data = 2.5
WRITE(6,*) a%data
END

Why is `std::ptr::null` not usable with unsized types?

As I understand, the standard (only?) way to make a null pointer in Rust is std::ptr::null.
However, that function is declared as follows.
pub const fn null<T>() -> *const T
In this declaration, T is implicitly assumed to have fixed size (otherwise, it would be T: ?Sized). As a consequence, it is impossible to use this function with *const str or *const [u32] for example. test it in the playground
Is there a good reason for excluding unsized types? What's wrong with wanting to create a null *const str?
A pointer to an unsized type is a fat pointer with two components: the pointer and the type metadata (a length for slices, and a vtable pointer for trait objects; in the future, Rust may allow other kinds of metadata). null only implies a value for the pointer part; there's no obvious choice for the other value. (You might think 0 is obvious for the length of a null slice pointer, and I can see the argument, but if the pointer is null it hardly matters how many things are there; you can't dereference it anyway, so making the size 0 is not necessary to ensure safety.)
There is no way to create a null pointer to a trait object, but as of Rust 1.42, you can use ptr::slice_from_raw_parts to create a null pointer to a slice. Let's suppose the length of the slice is 0:
use std::ptr;
fn main() {
let p: *const [u32] = ptr::slice_from_raw_parts(ptr::null(), 0);
println!("{:?}", p);
}
There is no equivalent function for str, but you could make one by creating a null *const [u8] and casting it with as.
This function (or the related slice_from_raw_parts_mut) is the only way to soundly create a null pointer to a slice. The usual way to get a raw pointer is by casting a reference, but references may never be null.

How to print dereferenced value of field without explicitly specifying that field golang

package main
import (
"fmt"
)
type outer struct {
in *int
}
func main() {
i := 4
o := outer{&i}
fmt.Printf("%+v", o)
}
I'd like to see {in:4} at the end of this, not {in:0x......}, i.e. pretty print the data structure.
I'd like to accomplish this in a similar manner to the code posted (e.g. with a fmt shortcut similar to %+v or an analogous solution).
This is for autogenerated code from a required field of a thrift struct.
What's the best way to go about this?
When you use &i it does not dereference i. Rather it references i, which means that it copies the address of i into o. See the documentation for the Address operators.
From what I gather, you should be able to use *o to dereference the pointer; in other words, go from the address back to the original variable.
For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. If x is nil, an attempt to evaluate *x will cause a run-time panic.

Is N-1 the largest term which could be used for Generic in VHDL

I am new to VHDL and I wanted to ask that what generic term could I use If i wanted to write any size of input vector which could be developed?
GENERIC (n1 : integer);
x:IN BIT_VECTOR(n1-1 downto 0);
Is that a correct example?
Your generic has no default value visible.
Your declaration for x is incomplete. It appears to be an entity declarative item with a mode while you don't have a port declaration.
This VHDL code is syntactically and semantically valid:
entity foo is
generic ( n1: integer);
port (
x: in bit_vector(n1-1 downto 0)
);
end entity;
architecture fum of foo is
begin
end architecture;
It will analyze. It can't be elaborated without the value of n1 being known:
entity foo_tb is
constant N_1: integer := 4;
end entity;
architecture fum of foo_tb is
signal x: bit_vector (N_1-1 downto 0);
begin
DUT:
entity work.foo
generic map (n1 => N_1)
port map ( x => x);
end architecture;
Entity foo by itself can't be the top level of an elaborated model because n1 isn't defined for elaboration.
Entity foo_tb can be elaborated, it uses the constant N_1 to supply a value to n1.
foo_tb can even be simulated, but it will exit immediately because there are no pending signal assignments after initialization.
Neither foo nor foo_tb can be synthesize. foo_tb because it has no ports and any logic in it's design hierarchy would be optimized away as unused. foo because it only has an output and is at best a constant.
If foo had multiple ports, with outputs depending on inputs it would be eligible for synthesis or simulation as long as the generic was defined for elaboration.
(And the moral here is to use a Minimal, Complete, and Verifiable example so someone doesn't have to wave their hands around it's shortcomings).
You can use every term, as far as it's result does not exceed the BIT_VECTORS's array range.
BIT_VECTOR definition: type BIT_VECTOR is array (NATURAL range <>) of BIT;
So your term can have results from 0 to 2**32 - 1
Term examples:
4*n1 - 1 downto 0
n1/4 + 8 downto 0
log2ceilnz(n1) - 1 downto 0
2**n1 - 1 downto 0
According to the " Paebbels" comment I edit this answer :
Every time you want to synthesize your code, synthesis tool should know about the size of parameters you used, Otherwise what exactly you want to synthesize ?!!! (what hardware ?!)
If you want to synthesize your top module code which contains a generic parameter in it's own entity, you can assign it with a default value such as the following code :
ENTITY ... IS
GENERIC(n1 : INTEGER := 8);
PORT(
-- use generic parameter
);
END ENTITY;
Also you can use the generic parameter inside architecture ( size of signals, index of loops, ... ).

C++11- Use nullptr all the time?

I'm just a little bit confused.
When should I use nullptr?
I've read on some sites that it should always be used, but I can't set nullptr for a non-pointer for example:
int myVar = nullptr; // Not a pointer ofcourse
Should I always use NULL non-pointers and nullptr for pointers?
Thanks to any help! I'm very new to c++ 11 (and c++ overall).
Always use nullptr when initializing pointers to a null pointer value, that's what it is meant for according to draft n3485.
[lex.nullptr] paragraph 1
The pointer literal is the keyword nullptr. It is a prvalue of type
std::nullptr_t. [ Note: std::nullptr_t is a distinct type that is
neither a pointer type nor a pointer to member type; rather, a prvalue
of this type is a null pointer constant and can be converted to a
null pointer value or null member pointer value. [...] — end note ]
Now onto the use of NULL.
According to the same draft it shall be defined as follows.
[diff.null] paragraph 1
The macro NULL, [...] is an
implementation-defined C ++ null pointer constant in this
International Standard.
and null pointer constant as follows.
[conv.ptr] paragraph 1
A null pointer constant is an integral constant expression [...]
prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t.
That is, it is implementation-defined behavior whether NULL is defined as an integer prvalue evaluating to zero, or a prvalue of type std::nullptr_t. If the given implementation of the standard library chooses the former, then NULL can be assigned to integer types and it's guaranteed it will be set to zero, but if the later is chosen, then the compiler is allowed to issue an error and declare the program ill-formed.
In other words, although conditionally valid [read IB], initializing an integer using NULL is most probably a bad idea, just use 0 instead.
On the other hand, according to the above NULL is guaranteed to initialize pointers to a null pointer value, much like nullptr does, but while NULL is a macro, what accompanies several caveats, nullptr is prvalue of a specific type, for which type checking and conversion rules apply. That's mostly why nullptr should be prefered.
consider the two function overloads:
void foo(int)
void foo(int*)
in C++, people tend to use 0 as a null value. Other people use NULL. (NULL is really just a fancy macro for 0)
If you call foo(0) or foo(NULL), it becomes ambiguous which one should be called. foo(nullptr) clears up this ambiguity, and will always call foo(int*).

Resources