comp.lang.ada
 help / color / mirror / Atom feed
* Need a way to convert a constant to a variable
@ 2017-08-05 13:41 Victor Porton
  2017-08-05 14:48 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Victor Porton @ 2017-08-05 13:41 UTC (permalink / raw)


I've sent the following email to ada-comment mailing list. I duplicate it 
here.

!topic Need a way to convert a constant to a variable
!reference Ada 2012 RM
!from Victor Porton 17-08-05
!keywords constant, variable, view, conversion
!discussion

Sometimes one needs to convert a constant view into variable view (I am
fully conscious that after this the programmer should take care not to
change the object of the view).

In the following (not compilable with GNAT 7.1.0) code I present my
best attempt to solve the following problem:

Write a function with an "in" indefinite holder with a string, return
chars_ptr corresponding to the string.

It looks like there is no solution of this in Ada 2012 :-(

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with Ada.Containers.Indefinite_Holders;

procedure Conv is

   package Char_Array_Holders is
      new Ada.Containers.Indefinite_Holders(char_array);

   type C_String_Holder is new Char_Array_Holders.Holder
      with null record;
   
   function To_C_String (Object: C_String_Holder) return chars_ptr is
      Value: char_array renames Constant_Reference(Object).Element.all;
      Value2: aliased Char_Array(Value'Range) with Import;
      for Value2'Address use Value'Address;
   begin
      return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
   end;
begin
   null;
end;

$ gnatgcc -c conv.adb -c conv.adb 
conv.adb:13:07: warning: aliased object has explicit bounds
conv.adb:13:07: warning: declare without bounds (and with explicit
initialization)
conv.adb:13:07: warning: for use with unconstrained access
conv.adb:16:46: object subtype must statically match designated subtype

My current workaround is to define my own "indefinite holder" type to
use it in my software instead of Ada.Containers.Indefinite_Holders.

I propose the following language change:

Please add 'Unchecked_Variable attribute.

There are two possible meanings (of which we should choose one) of the
attribute:

1. C'Unchecked_Variable returns a variable view of a constant C.

2. A'Unchecked_Variable returns the corresponding access to a variable
for an access A to constant.

Both variants seem to solve the trouble.

Can any problem with different representation of constant and variables
appear?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41 Need a way to convert a constant to a variable Victor Porton
@ 2017-08-05 14:48 ` Dmitry A. Kazakov
  2017-08-05 15:11   ` Victor Porton
  2017-08-05 15:41 ` Jeffrey R. Carter
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2017-08-05 14:48 UTC (permalink / raw)


On 2017-08-05 15:41, Victor Porton wrote:
> I've sent the following email to ada-comment mailing list. I duplicate it
> here.
> 
> !topic Need a way to convert a constant to a variable
> !reference Ada 2012 RM
> !from Victor Porton 17-08-05
> !keywords constant, variable, view, conversion
> !discussion
> 
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> 
> In the following (not compilable with GNAT 7.1.0) code I present my
> best attempt to solve the following problem:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.
> 
> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> with Ada.Containers.Indefinite_Holders;
> 
> procedure Conv is
> 
>     package Char_Array_Holders is
>        new Ada.Containers.Indefinite_Holders(char_array);
> 
>     type C_String_Holder is new Char_Array_Holders.Holder
>        with null record;
>     
>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>        Value: char_array renames Constant_Reference(Object).Element.all;
>        Value2: aliased Char_Array(Value'Range) with Import;
>        for Value2'Address use Value'Address;
>     begin
>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>     end;
> begin
>     null;
> end;

AFAIK, Ada.Containers.Indefinite_Holders was designed in a way to 
prevent specifically what you want.

> Can any problem with different representation of constant and variables
> appear?

1. Don't use Ada.Containers.Indefinite_Holders?

2. Don't use char_array. It has restricted use when interfacing C. You 
probably need chars_ptr put into a controlled type if you want safe C 
strings. This is basically same as Holder internally is, except that you 
are in full control.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 14:48 ` Dmitry A. Kazakov
@ 2017-08-05 15:11   ` Victor Porton
  2017-08-05 16:44     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: Victor Porton @ 2017-08-05 15:11 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> On 2017-08-05 15:41, Victor Porton wrote:
>> I've sent the following email to ada-comment mailing list. I duplicate it
>> here.
>> 
>> !topic Need a way to convert a constant to a variable
>> !reference Ada 2012 RM
>> !from Victor Porton 17-08-05
>> !keywords constant, variable, view, conversion
>> !discussion
>> 
>> Sometimes one needs to convert a constant view into variable view (I am
>> fully conscious that after this the programmer should take care not to
>> change the object of the view).
>> 
>> In the following (not compilable with GNAT 7.1.0) code I present my
>> best attempt to solve the following problem:
>> 
>> Write a function with an "in" indefinite holder with a string, return
>> chars_ptr corresponding to the string.
>> 
>> It looks like there is no solution of this in Ada 2012 :-(
>> 
>> with Interfaces.C; use Interfaces.C;
>> with Interfaces.C.Strings; use Interfaces.C.Strings;
>> with Ada.Containers.Indefinite_Holders;
>> 
>> procedure Conv is
>> 
>>     package Char_Array_Holders is
>>        new Ada.Containers.Indefinite_Holders(char_array);
>> 
>>     type C_String_Holder is new Char_Array_Holders.Holder
>>        with null record;
>>     
>>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>>        Value: char_array renames Constant_Reference(Object).Element.all;
>>        Value2: aliased Char_Array(Value'Range) with Import;
>>        for Value2'Address use Value'Address;
>>     begin
>>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>>     end;
>> begin
>>     null;
>> end;
> 
> AFAIK, Ada.Containers.Indefinite_Holders was designed in a way to
> prevent specifically what you want.
> 
>> Can any problem with different representation of constant and variables
>> appear?
> 
> 1. Don't use Ada.Containers.Indefinite_Holders?
> 
> 2. Don't use char_array. It has restricted use when interfacing C. You
> probably need chars_ptr put into a controlled type if you want safe C
> strings. This is basically same as Holder internally is, except that you
> are in full control.

I do use char_array for interfacing with C.

It is a pity that I need to reimplement Indefinite_Holders for this task.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41 Need a way to convert a constant to a variable Victor Porton
  2017-08-05 14:48 ` Dmitry A. Kazakov
@ 2017-08-05 15:41 ` Jeffrey R. Carter
  2017-08-05 16:25   ` Victor Porton
  2017-08-05 17:59 ` Per Sandberg
  2017-08-15 20:05 ` Eryndlia Mavourneen
  3 siblings, 1 reply; 12+ messages in thread
From: Jeffrey R. Carter @ 2017-08-05 15:41 UTC (permalink / raw)


On 08/05/2017 03:41 PM, Victor Porton wrote:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.

Your requirements are for an indefinite holder with a string, but your attempted 
solution is for an indefinite holder with a char_array. I will assume you meant 
an indefinite holder with a char_array.

> It looks like there is no solution of this in Ada 2012 :-(

with Ada.Containers.Indefinite_Holders;
with Interfaces.C.Strings;

package Conv is
    package C_Str_Holders is new Ada.Containers.Indefinite_Holders
       (Element_Type => Interfaces.C.Char_Array, "=" => Interfaces.C."=");

    function To_Chars_Ptr (Item : C_Str_Holders.Holder)
                        return Interfaces.C.Strings.Chars_Ptr is
       (Interfaces.C.Strings.New_Char_Array (Item.Element) );
end Conv;

This compiles fine, so clearly there is a way to do this without a language change.

-- 
Jeff Carter
"He didn't get that nose from playing ping-pong."
Never Give a Sucker an Even Break
110

---
This email has been checked for viruses by AVG.
http://www.avg.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 15:41 ` Jeffrey R. Carter
@ 2017-08-05 16:25   ` Victor Porton
  2017-08-05 20:12     ` Jeffrey R. Carter
  0 siblings, 1 reply; 12+ messages in thread
From: Victor Porton @ 2017-08-05 16:25 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> On 08/05/2017 03:41 PM, Victor Porton wrote:
>> 
>> Write a function with an "in" indefinite holder with a string, return
>> chars_ptr corresponding to the string.
> 
> Your requirements are for an indefinite holder with a string, but your
> attempted solution is for an indefinite holder with a char_array. I will
> assume you meant an indefinite holder with a char_array.

Yes, my typo. I am about an indefinite holder with a char_array.

>> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Ada.Containers.Indefinite_Holders;
> with Interfaces.C.Strings;
> 
> package Conv is
>     package C_Str_Holders is new Ada.Containers.Indefinite_Holders
>        (Element_Type => Interfaces.C.Char_Array, "=" => Interfaces.C."=");
> 
>     function To_Chars_Ptr (Item : C_Str_Holders.Holder)
>                         return Interfaces.C.Strings.Chars_Ptr is
>        (Interfaces.C.Strings.New_Char_Array (Item.Element) );
> end Conv;
> 
> This compiles fine, so clearly there is a way to do this without a
> language change.

Your code allocates a new string which requires to be freed later.

I want a function, which would return a pointer to the (not necessarily nul-
terminated) string hold in the indefinite holder, so that deallocation would 
be not required and code would be more efficient (not requiring to copy the 
char_array).

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 15:11   ` Victor Porton
@ 2017-08-05 16:44     ` Dmitry A. Kazakov
  2017-08-05 17:45       ` Victor Porton
  0 siblings, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2017-08-05 16:44 UTC (permalink / raw)


On 2017-08-05 17:11, Victor Porton wrote:

> I do use char_array for interfacing with C.

You should probably reconsider it. It works only for C functions that do 
not expect null as a value, do not return strings allocated outside Ada, 
do not deallocate strings passed into.

> It is a pity that I need to reimplement Indefinite_Holders for this task.

Why re-implement? It has different purpose.

I never used it because of its semantics. I use a different approach, 
maybe because it was Ada 95 when first implemented. Anyway, it works 
better to me. I don't like the overhead of creating messy temporary 
controlled helper types.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 16:44     ` Dmitry A. Kazakov
@ 2017-08-05 17:45       ` Victor Porton
  2017-08-05 19:37         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: Victor Porton @ 2017-08-05 17:45 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> On 2017-08-05 17:11, Victor Porton wrote:
> 
>> I do use char_array for interfacing with C.
> 
> You should probably reconsider it. It works only for C functions that do
> not expect null as a value, do not return strings allocated outside Ada,
> do not deallocate strings passed into.

I use an indefinite holder with char_array inside to represent a C string 
(whose length size_t value ('Length in Ada) I pass separately to a C 
function), which may be either a real string (corresponding to char_array) 
or NULL (corresponding to empty indefinite handler).

Note that the above is NOT related to NUL-terminated strings.

>> It is a pity that I need to reimplement Indefinite_Holders for this task.


-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41 Need a way to convert a constant to a variable Victor Porton
  2017-08-05 14:48 ` Dmitry A. Kazakov
  2017-08-05 15:41 ` Jeffrey R. Carter
@ 2017-08-05 17:59 ` Per Sandberg
  2017-08-15 20:05 ` Eryndlia Mavourneen
  3 siblings, 0 replies; 12+ messages in thread
From: Per Sandberg @ 2017-08-05 17:59 UTC (permalink / raw)


????
A constant shall never ever change its value since the compiler is free 
to use the value in compile time to optimize the code if possible.

So the whole suggestion is screaming "I want to do a very bad design".

/P


Den 2017-08-05 kl. 15:41, skrev Victor Porton:
> I've sent the following email to ada-comment mailing list. I duplicate it
> here.
> 
> !topic Need a way to convert a constant to a variable
> !reference Ada 2012 RM
> !from Victor Porton 17-08-05
> !keywords constant, variable, view, conversion
> !discussion
> 
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> 
> In the following (not compilable with GNAT 7.1.0) code I present my
> best attempt to solve the following problem:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.
> 
> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> with Ada.Containers.Indefinite_Holders;
> 
> procedure Conv is
> 
>     package Char_Array_Holders is
>        new Ada.Containers.Indefinite_Holders(char_array);
> 
>     type C_String_Holder is new Char_Array_Holders.Holder
>        with null record;
>     
>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>        Value: char_array renames Constant_Reference(Object).Element.all;
>        Value2: aliased Char_Array(Value'Range) with Import;
>        for Value2'Address use Value'Address;
>     begin
>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>     end;
> begin
>     null;
> end;
> 
> $ gnatgcc -c conv.adb -c conv.adb
> conv.adb:13:07: warning: aliased object has explicit bounds
> conv.adb:13:07: warning: declare without bounds (and with explicit
> initialization)
> conv.adb:13:07: warning: for use with unconstrained access
> conv.adb:16:46: object subtype must statically match designated subtype
> 
> My current workaround is to define my own "indefinite holder" type to
> use it in my software instead of Ada.Containers.Indefinite_Holders.
> 
> I propose the following language change:
> 
> Please add 'Unchecked_Variable attribute.
> 
> There are two possible meanings (of which we should choose one) of the
> attribute:
> 
> 1. C'Unchecked_Variable returns a variable view of a constant C.
> 
> 2. A'Unchecked_Variable returns the corresponding access to a variable
> for an access A to constant.
> 
> Both variants seem to solve the trouble.
> 
> Can any problem with different representation of constant and variables
> appear?
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 17:45       ` Victor Porton
@ 2017-08-05 19:37         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2017-08-05 19:37 UTC (permalink / raw)


On 2017-08-05 19:45, Victor Porton wrote:
> Dmitry A. Kazakov wrote:
> 
>> On 2017-08-05 17:11, Victor Porton wrote:
>>
>>> I do use char_array for interfacing with C.
>>
>> You should probably reconsider it. It works only for C functions that do
>> not expect null as a value, do not return strings allocated outside Ada,
>> do not deallocate strings passed into.
> 
> I use an indefinite holder with char_array inside to represent a C string
> (whose length size_t value ('Length in Ada) I pass separately to a C
> function), which may be either a real string (corresponding to char_array)
> or NULL (corresponding to empty indefinite handler).
> 
> Note that the above is NOT related to NUL-terminated strings.

Yes. What you do is not a good idea. Try this instead:

    type C_String is new Ada.Finalization.Limited_Controlled with record
       Data : chars_ptr := null_ptr;
    end record;
    procedure Set (X : in out C_String; Text : String) is
    begin
       Free (X.Data);
       X.Data := New_String (Text);
    end Set;
    procedure Finalize (X : in out C_String) is
    begin
       Free (X.Data);
    end Finalize;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 16:25   ` Victor Porton
@ 2017-08-05 20:12     ` Jeffrey R. Carter
  0 siblings, 0 replies; 12+ messages in thread
From: Jeffrey R. Carter @ 2017-08-05 20:12 UTC (permalink / raw)


On 08/05/2017 06:25 PM, Victor Porton wrote:
> 
> Your code allocates a new string which requires to be freed later.
> 
> I want a function, which would return a pointer to the (not necessarily nul-
> terminated) string hold in the indefinite holder, so that deallocation would
> be not required and code would be more efficient (not requiring to copy the
> char_array).

You made a proposal to the ARG, and I showed that the problem in that proposal 
that you claim cannot be solved with the existing language can be. The ARG 
aren't going to look at the problem you have in your mind, they're going to look 
at the problem in your proposal. Since it can be so solved, the ARG will reject it.

But even if you clean it up to include all your internal requirements I still 
think it won't fly. Ada is a safe language, and a blatantly unsafe feature such 
as you are requesting will only be considered if it is applicable to a large set 
of real problems. Not only that, but you'll need to show that this large set of 
real problems has many with real size and timing requirements that can't be met 
using my solution. In other words, all your requirements must be realistic, not 
premature optimization. The ARG is going to need be told why in these problems 
the functions can't have an in-out parameter, for example.

So I think your proposal will fail on that count.

Furthermore, your only example uses a container from the standard library. The 
containers are intended to be general purpose and safe. They are not expected to 
be usable for every problem. So your large set of real problems will have to 
have this problem not in connection with the containers. Otherwise they'll say 
that if the containers are not suitable for your problem, don't use them.

Even if you can show all this, I still think it won't fly, because I know a way 
to do what you want within the existing language.

I suggest your effort would be better spent considering alternative designs.

-- 
Jeff Carter
"He didn't get that nose from playing ping-pong."
Never Give a Sucker an Even Break
110

---
This email has been checked for viruses by AVG.
http://www.avg.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41 Need a way to convert a constant to a variable Victor Porton
                   ` (2 preceding siblings ...)
  2017-08-05 17:59 ` Per Sandberg
@ 2017-08-15 20:05 ` Eryndlia Mavourneen
  2017-08-15 20:07   ` Eryndlia Mavourneen
  3 siblings, 1 reply; 12+ messages in thread
From: Eryndlia Mavourneen @ 2017-08-15 20:05 UTC (permalink / raw)


On Saturday, August 5, 2017 at 8:41:26 AM UTC-5, Victor Porton wrote:
> ...
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> ...
> Victor Porton - http://portonvictor.org

Aside from any language-specific issues, I would expect Ada to allocate a constant  in a Read-Only program section for the linkage editor.  If it does this and nothing else is done in the linker, then any attempt to write a constant would fail with a hardware exception.

-- Eryndlia (KK1T)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Need a way to convert a constant to a variable
  2017-08-15 20:05 ` Eryndlia Mavourneen
@ 2017-08-15 20:07   ` Eryndlia Mavourneen
  0 siblings, 0 replies; 12+ messages in thread
From: Eryndlia Mavourneen @ 2017-08-15 20:07 UTC (permalink / raw)


On Tuesday, August 15, 2017 at 3:05:52 PM UTC-5, Eryndlia Mavourneen wrote:
> On Saturday, August 5, 2017 at 8:41:26 AM UTC-5, Victor Porton wrote:
> > ...
> > Sometimes one needs to convert a constant view into variable view (I am
> > fully conscious that after this the programmer should take care not to
> > change the object of the view).
> > ...
> > Victor Porton - http://portonvictor.org
> 
> Aside from any language-specific issues, I would expect Ada to allocate a constant  in a Read-Only program section for the linkage editor.  If it does this and nothing else is done in the linker, then any attempt to write a constant would fail with a hardware exception.
> 
> -- Eryndlia (KK1T)

Note that I use Windows 10 and I enable DEP (Data Execution Prevention).

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-08-15 20:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-05 13:41 Need a way to convert a constant to a variable Victor Porton
2017-08-05 14:48 ` Dmitry A. Kazakov
2017-08-05 15:11   ` Victor Porton
2017-08-05 16:44     ` Dmitry A. Kazakov
2017-08-05 17:45       ` Victor Porton
2017-08-05 19:37         ` Dmitry A. Kazakov
2017-08-05 15:41 ` Jeffrey R. Carter
2017-08-05 16:25   ` Victor Porton
2017-08-05 20:12     ` Jeffrey R. Carter
2017-08-05 17:59 ` Per Sandberg
2017-08-15 20:05 ` Eryndlia Mavourneen
2017-08-15 20:07   ` Eryndlia Mavourneen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox