* Unchecked_Union record inside an other record - trouble
@ 2014-08-08 15:36 Victor Porton
2014-08-08 16:01 ` Adam Beneschan
2014-08-08 19:21 ` Per Sandberg
0 siblings, 2 replies; 17+ messages in thread
From: Victor Porton @ 2014-08-08 15:36 UTC (permalink / raw)
I am trying to interface my program with a C library.
The below program does not compile:
main.adb:19:14: unconstrained subtype in component declaration
If this does not work, what should I do to interface a union inside a struct
in a C library?
-- main.adb
with Interfaces.C; use Interfaces.C;
procedure Main is
type Kind is (First, Second);
type T(K: Kind) is
record
case K is
when First => I: int;
when Second => C: char;
end case;
end record
with Unchecked_Union, Convention=>C;
type T2 is
record
Z: int;
Ob: T;
end record
with Convention=>C;
begin
null;
end;
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 15:36 Unchecked_Union record inside an other record - trouble Victor Porton
@ 2014-08-08 16:01 ` Adam Beneschan
2014-08-08 16:56 ` Victor Porton
2014-08-08 19:52 ` Victor Porton
2014-08-08 19:21 ` Per Sandberg
1 sibling, 2 replies; 17+ messages in thread
From: Adam Beneschan @ 2014-08-08 16:01 UTC (permalink / raw)
On Friday, August 8, 2014 8:36:48 AM UTC-7, Victor Porton wrote:
> I am trying to interface my program with a C library.
> The below program does not compile:
> main.adb:19:14: unconstrained subtype in component declaration
> If this does not work, what should I do to interface a union inside a struct
> in a C library?
> -- main.adb
>
> with Interfaces.C; use Interfaces.C;
> procedure Main is
> type Kind is (First, Second);
> type T(K: Kind) is
change this to
type T(K: Kind := Kind'First) is
-- Adam
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 16:01 ` Adam Beneschan
@ 2014-08-08 16:56 ` Victor Porton
2014-08-08 18:52 ` Shark8
2014-08-08 19:52 ` Victor Porton
1 sibling, 1 reply; 17+ messages in thread
From: Victor Porton @ 2014-08-08 16:56 UTC (permalink / raw)
Adam Beneschan wrote:
> On Friday, August 8, 2014 8:36:48 AM UTC-7, Victor Porton wrote:
>> I am trying to interface my program with a C library.
>
>> The below program does not compile:
>> main.adb:19:14: unconstrained subtype in component declaration
>
>> If this does not work, what should I do to interface a union inside a
>> struct in a C library?
>
>> -- main.adb
>>
>> with Interfaces.C; use Interfaces.C;
>
>> procedure Main is
>
>> type Kind is (First, Second);
>
>> type T(K: Kind) is
>
> change this to
>
> type T(K: Kind := Kind'First) is
Done.
But it is a hack.
I propose to change ARM not to require a discriminant in this specific case
(Unchecked_Union).
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 16:56 ` Victor Porton
@ 2014-08-08 18:52 ` Shark8
2014-08-08 19:56 ` Victor Porton
0 siblings, 1 reply; 17+ messages in thread
From: Shark8 @ 2014-08-08 18:52 UTC (permalink / raw)
On 08-Aug-14 10:56, Victor Porton wrote:
>
> But it is a hack.
How are you going to be able to tell which variant the subcomponent is
though? The C union *doesn't* tag the varying part, so that information
has to be kept elsewhere... or ignored completely.
> I propose to change ARM not to require a discriminant in this specific case
> (Unchecked_Union).
No.
Just no.
What you propose here would import from C weak typing -- if you want
weak typing, why re you using Ada?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 15:36 Unchecked_Union record inside an other record - trouble Victor Porton
2014-08-08 16:01 ` Adam Beneschan
@ 2014-08-08 19:21 ` Per Sandberg
2014-08-08 20:01 ` Victor Porton
2014-08-08 21:23 ` Jeffrey Carter
1 sibling, 2 replies; 17+ messages in thread
From: Per Sandberg @ 2014-08-08 19:21 UTC (permalink / raw)
You shall not try to write interface code by hand you shall use the
compiler
gcc -c -fdump-ada-spec <more arguments and files>
see GNAT Users guide.
Since humans makes a heap load of errors and erronous asumptions when
they try to translate the contents of a .h file to an .ads file, the
compiler does a much better job.
/Per
On 08.08.2014 17:36, Victor Porton wrote:
> I am trying to interface my program with a C library.
>
> The below program does not compile:
>
> main.adb:19:14: unconstrained subtype in component declaration
>
> If this does not work, what should I do to interface a union inside a struct
> in a C library?
>
> -- main.adb
> with Interfaces.C; use Interfaces.C;
>
> procedure Main is
>
> type Kind is (First, Second);
>
> type T(K: Kind) is
> record
> case K is
> when First => I: int;
> when Second => C: char;
> end case;
> end record
> with Unchecked_Union, Convention=>C;
>
> type T2 is
> record
> Z: int;
> Ob: T;
> end record
> with Convention=>C;
>
> begin
> null;
> end;
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 16:01 ` Adam Beneschan
2014-08-08 16:56 ` Victor Porton
@ 2014-08-08 19:52 ` Victor Porton
2014-08-08 19:57 ` Adam Beneschan
1 sibling, 1 reply; 17+ messages in thread
From: Victor Porton @ 2014-08-08 19:52 UTC (permalink / raw)
Adam Beneschan wrote:
> On Friday, August 8, 2014 8:36:48 AM UTC-7, Victor Porton wrote:
>> I am trying to interface my program with a C library.
>
>> The below program does not compile:
>> main.adb:19:14: unconstrained subtype in component declaration
>
>> If this does not work, what should I do to interface a union inside a
>> struct in a C library?
>
>> -- main.adb
>>
>> with Interfaces.C; use Interfaces.C;
>
>> procedure Main is
>
>> type Kind is (First, Second);
>
>> type T(K: Kind) is
>
> change this to
>
> type T(K: Kind := Kind'First) is
OK, I followed your way, Adam.
But it produces a warning with GNAT 4.9 (for the below program):
gnatmake -q -c -gnatc -u -P/home/porton/t/default.gpr main.adb --subdirs=check -cargs -g -O0 -gnato -fstack-check -gnatVa
main.adb:26:17: warning: component not present in subtype of "T" defined at line 21
main.adb:26:17: warning: "Constraint_Error" will be raised at run time
Should I just disable this warning? (BTW, how to disable this warning in
GNAT-GPS?)
It seems that there will be a "Constraint_Error" and this is really bad.
Any other idea/workarounds?
-- main.adb
with Interfaces.C; use Interfaces.C;
procedure Main is
type Kind is (First, Second);
type T(K: Kind) is
record
case K is
when First =>
X: int;
when Second =>
Y: char;
end case;
end record
with Unchecked_Union, Convention=>C;
type Container is
record
Z: int;
R: T(Kind'First);
end record;
function P (C: Container) return char is
begin
return C.R.Y;
end;
begin
null;
end;
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 18:52 ` Shark8
@ 2014-08-08 19:56 ` Victor Porton
2014-08-08 20:06 ` Pascal Obry
2014-08-08 20:09 ` Shark8
0 siblings, 2 replies; 17+ messages in thread
From: Victor Porton @ 2014-08-08 19:56 UTC (permalink / raw)
Shark8 wrote:
> On 08-Aug-14 10:56, Victor Porton wrote:
>>
>> But it is a hack.
>
> How are you going to be able to tell which variant the subcomponent is
> though? The C union *doesn't* tag the varying part, so that information
> has to be kept elsewhere... or ignored completely.
For records interfacing with C it SHOULD be ignored completely. Because it
is C.
>> I propose to change ARM not to require a discriminant in this specific
>> case (Unchecked_Union).
>
> No.
> Just no.
> What you propose here would import from C weak typing -- if you want
> weak typing, why re you using Ada?
I want weak typing on request, to interface with C, but remaining in Ada.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 19:52 ` Victor Porton
@ 2014-08-08 19:57 ` Adam Beneschan
0 siblings, 0 replies; 17+ messages in thread
From: Adam Beneschan @ 2014-08-08 19:57 UTC (permalink / raw)
On Friday, August 8, 2014 12:52:41 PM UTC-7, Victor Porton wrote:
> Adam Beneschan wrote:
> OK, I followed your way, Adam.
No, you didn't. Please reread my response carefully.
-- Adam
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 19:21 ` Per Sandberg
@ 2014-08-08 20:01 ` Victor Porton
2014-08-08 21:23 ` Jeffrey Carter
1 sibling, 0 replies; 17+ messages in thread
From: Victor Porton @ 2014-08-08 20:01 UTC (permalink / raw)
Per Sandberg wrote:
> You shall not try to write interface code by hand you shall use the
> compiler
> gcc -c -fdump-ada-spec <more arguments and files>
> see GNAT Users guide.
>
> Since humans makes a heap load of errors and erronous asumptions when
> they try to translate the contents of a .h file to an .ads file, the
> compiler does a much better job.
I considered this approach but refused to use auto-generated code.
One reason is that it uses a system address type where it should be access
arguments to a function. In my opinion, this is not guaranteed to work by
ARM.
The other reason is that I can fine tune types. One especially useful usage
pattern is that I sometimes pass char_array and sometimes chars_ptr to a
function which requires a char or a void pointer. Also I can differentiate
"access" arguments and pass-by-value, what is a sometimes useful
distinction.
This use case simplifies my coding probably more that the necessity to write
imported C functions manually.
And last it does not take really much time to code imported C functions
manually. I may make errors here, but as for now I've instead found a few
errors in the C library with which I am trying to interface.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 19:56 ` Victor Porton
@ 2014-08-08 20:06 ` Pascal Obry
2014-08-08 20:09 ` Shark8
1 sibling, 0 replies; 17+ messages in thread
From: Pascal Obry @ 2014-08-08 20:06 UTC (permalink / raw)
Le vendredi 08 août 2014 à 22:56 +0300, Victor Porton a écrit :
> For records interfacing with C it SHOULD be ignored completely. Because it
> is C.
But again in Ada all must be explicit, this probably fall under this
rule. And what if you want to emulate the Ada tag on the C side and
actually have the tag exported? Not sure this is a real example as it
heavily depends on the compiler (and so the generated code).
--
Pascal Obry / Magny Les Hameaux (78)
The best way to travel is by means of imagination
http://v2p.fr.eu.org
http://www.obry.net
gpg --keyserver keys.gnupg.net --recv-key F949BD3B
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 19:56 ` Victor Porton
2014-08-08 20:06 ` Pascal Obry
@ 2014-08-08 20:09 ` Shark8
2014-08-08 20:12 ` Victor Porton
1 sibling, 1 reply; 17+ messages in thread
From: Shark8 @ 2014-08-08 20:09 UTC (permalink / raw)
On 08-Aug-14 13:56, Victor Porton wrote:
> For records interfacing with C it SHOULD be ignored completely. Because it
> is C.
Not in your example; the subcomponent is part of a record which is *not*
a C-style union, it should therefore store the proper tag value
(discriminant) in its own discriminant.
type T2(K: Kind) is
record
Z: int;
Ob: T(K);
end record
with Convention=>C;
Yields:
warning: variant record has no direct equivalent in C
warning: use of convention for type "T2" is dubious
So, remove Convention => C.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 20:09 ` Shark8
@ 2014-08-08 20:12 ` Victor Porton
2014-08-08 20:22 ` Shark8
0 siblings, 1 reply; 17+ messages in thread
From: Victor Porton @ 2014-08-08 20:12 UTC (permalink / raw)
Shark8 wrote:
> On 08-Aug-14 13:56, Victor Porton wrote:
>> For records interfacing with C it SHOULD be ignored completely. Because
>> it is C.
>
> Not in your example; the subcomponent is part of a record which is *not*
> a C-style union, it should therefore store the proper tag value
> (discriminant) in its own discriminant.
>
> type T2(K: Kind) is
> record
> Z: int;
> Ob: T(K);
> end record
> with Convention=>C;
>
> Yields:
> warning: variant record has no direct equivalent in C
> warning: use of convention for type "T2" is dubious
> So, remove Convention => C.
You forgot "with Unchecked_Union". Certainly your code does not work.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 20:12 ` Victor Porton
@ 2014-08-08 20:22 ` Shark8
2014-08-08 20:28 ` Victor Porton
0 siblings, 1 reply; 17+ messages in thread
From: Shark8 @ 2014-08-08 20:22 UTC (permalink / raw)
On 08-Aug-14 14:12, Victor Porton wrote:
> You forgot "with Unchecked_Union". Certainly your code does not work.
There's no unchecked union on T2, that was T in your example.
>
> type T(K: Kind) is
> record
> case K is
> when First => I: int;
> when Second => C: char;
> end case;
> end record
> with Unchecked_Union, Convention=>C;
>
> type T2 is
> record
> Z: int;
> Ob: T;
> end record
> with Convention=>C;
See?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 20:22 ` Shark8
@ 2014-08-08 20:28 ` Victor Porton
2014-08-08 21:07 ` Shark8
0 siblings, 1 reply; 17+ messages in thread
From: Victor Porton @ 2014-08-08 20:28 UTC (permalink / raw)
Shark8 wrote:
> On 08-Aug-14 14:12, Victor Porton wrote:
>> You forgot "with Unchecked_Union". Certainly your code does not work.
>
> There's no unchecked union on T2, that was T in your example.
>
>>
>> type T(K: Kind) is
>> record
>> case K is
>> when First => I: int;
>> when Second => C: char;
>> end case;
>> end record
>> with Unchecked_Union, Convention=>C;
>>
>> type T2 is
>> record
>> Z: int;
>> Ob: T;
>> end record
>> with Convention=>C;
>
> See?
GNAT 4.9 produces no warnings for the below program.
Which compiler do you use? I suspect it is a bug in your compiler.
Or do we speak about different Ada code?
-- main.adb
with Interfaces.C; use Interfaces.C;
procedure Main is
type Kind is (First, Second);
type T(K: Kind := Kind'Last) is
record
case K is
when First =>
X: int;
when Second =>
Y: char;
end case;
end record
with Unchecked_Union, Convention=>C;
type Container is
record
Z: int;
R: T;
end record;
function P (C: Container) return char is
begin
return C.R.Y;
end;
begin
null;
end;
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 20:28 ` Victor Porton
@ 2014-08-08 21:07 ` Shark8
0 siblings, 0 replies; 17+ messages in thread
From: Shark8 @ 2014-08-08 21:07 UTC (permalink / raw)
On 08-Aug-14 14:28, Victor Porton wrote:
>
> Which compiler do you use? I suspect it is a bug in your compiler.
I'm using GNAT GPL 2013 (apparently 4.7.4)
> Or do we speak about different Ada code?
Well, given what you just posted, it looks like you renamed "T2" to
"Container".
> function P (C: Container) return char is
> begin
> return C.R.Y;
> end;
Your Container type probably needs a tag.
Your function P should probably be something more like:
function P (C: Container) return Character is
Subtype Character_T is T(K => Second);
Function Convert is new Unchecked_Conversion(
Source => T,
Target => Character_T
);
begin
return Convert(C.R).Y; -- This ensures we get the character.
end;
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 19:21 ` Per Sandberg
2014-08-08 20:01 ` Victor Porton
@ 2014-08-08 21:23 ` Jeffrey Carter
2014-08-10 7:25 ` Per Sandberg
1 sibling, 1 reply; 17+ messages in thread
From: Jeffrey Carter @ 2014-08-08 21:23 UTC (permalink / raw)
On 08/08/2014 12:21 PM, Per Sandberg wrote:
> You shall not try to write interface code by hand you shall use the compiler
> gcc -c -fdump-ada-spec <more arguments and files>
> see GNAT Users guide.
>
> Since humans makes a heap load of errors and erronous asumptions when they try
> to translate the contents of a .h file to an .ads file, the compiler does a much
> better job.
While I agree with you in general, the results of -fdump-ada-spec need to be
manually massaged since it produces non-portable, compiler-dependent code, such
as using Address for C pointers. It may also be preferable to create a binding
by hand if you only want a small subset of a large header.
--
Jeff Carter
"We call your door-opening request a silly thing."
Monty Python & the Holy Grail
17
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Unchecked_Union record inside an other record - trouble
2014-08-08 21:23 ` Jeffrey Carter
@ 2014-08-10 7:25 ` Per Sandberg
0 siblings, 0 replies; 17+ messages in thread
From: Per Sandberg @ 2014-08-10 7:25 UTC (permalink / raw)
Yes of couse -fdump-ada-spec is for GCC-gnat but even if you want to
take a small subset I find it more efficent and much less errorprone to
start with the generated spec:s and edit the generated code afterwards.
(have done this with a fairtly large API:
550 header-files
7500 methods
5500 types
and some small ones as well.
/per
On 08.08.2014 23:23, Jeffrey Carter wrote:
> On 08/08/2014 12:21 PM, Per Sandberg wrote:
>> You shall not try to write interface code by hand you shall use the
>> compiler
>> gcc -c -fdump-ada-spec <more arguments and files>
>> see GNAT Users guide.
>>
>> Since humans makes a heap load of errors and erronous asumptions when
>> they try
>> to translate the contents of a .h file to an .ads file, the compiler
>> does a much
>> better job.
>
> While I agree with you in general, the results of -fdump-ada-spec need
> to be manually massaged since it produces non-portable,
> compiler-dependent code, such as using Address for C pointers. It may
> also be preferable to create a binding by hand if you only want a small
> subset of a large header.
>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2014-08-10 7:25 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-08 15:36 Unchecked_Union record inside an other record - trouble Victor Porton
2014-08-08 16:01 ` Adam Beneschan
2014-08-08 16:56 ` Victor Porton
2014-08-08 18:52 ` Shark8
2014-08-08 19:56 ` Victor Porton
2014-08-08 20:06 ` Pascal Obry
2014-08-08 20:09 ` Shark8
2014-08-08 20:12 ` Victor Porton
2014-08-08 20:22 ` Shark8
2014-08-08 20:28 ` Victor Porton
2014-08-08 21:07 ` Shark8
2014-08-08 19:52 ` Victor Porton
2014-08-08 19:57 ` Adam Beneschan
2014-08-08 19:21 ` Per Sandberg
2014-08-08 20:01 ` Victor Porton
2014-08-08 21:23 ` Jeffrey Carter
2014-08-10 7:25 ` Per Sandberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox