Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0000467OCamlCamlIDLpublic2001-08-01 17:462001-08-08 17:18
Reporteradministrator 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000467: camlidl: some array-related problems
Description1. In contrast with what the manual says, "unique" attribute is not
applicable to arrays and should be ignored (array is not l-value and cannot
be equal to NULL). Currently incorrect C-code is generated:

typedef struct
{
  int len;
  [length_is(len),unique] char data[10];
} Array1;

 |
 V

typedef struct {
  int len;
  char data[10];
} Array1;

void camlidl_ml2c_array_Array1(value _v1, Array1 * _c2, camlidl_ctx _ctx)
{
value _v3;
mlsize_t _c4;
mlsize_t _c5;
value _v6;
if (_v1 == Val_int(0)) {
  (*_c2).data = NULL; /* syntax error, data is not l-value! */
} else {
  _v3 = Field(_v1, 0);
  _c4 = Wosize_val(_v3);
  if (_c4 != 10) invalid_argument("typedef Array1");
  for (_c5 = 0; _c5 < 10; _c5++) {
    _v6 = Field(_v3, _c5);
    (*_c2).data[_c5] = Int_val(_v6);
  }
}
}

2. It's impossible to create bigarray of the fixed size -- pointer (not
array) is always created:

typedef struct
{
  int len;
  [length_is(len)] int data[10];
} Array2;

typedef struct
{
  int len;
  [length_is(len),bigarray] int data[10];
} BigArray;

 |
 V

typedef struct
{
  int len;
  int data[10];
} Array2;

typedef struct {
  int len;
  int *data; /* why not data[10]? */
} BigArray;

3. Arrays of non-specified size are treated as pointers, but MIDL treats
them differently:

typedef struct
{
  int len;
  [size_is(len)] int data[];
} Array3;

 |
 V

camlidl:

typedef struct {
  int len;
  int *data;
} Array3;

midl:

typedef /* [public] */ struct __MIDL___MIDL_itf_array_0000_0002
    {
    int len;
    /* [length_is] */ int data[ 1 ];
    } Array3;

I would prefer the MIDL way, because otherwise we cannot properly describe
C-structures where array (not pointer) is used, but its size is not
known. Of course, these arrays can only be used as [in] parameters, and
ML->C conversion functions should not be generated (if we need [out]
structure, we should use pointer, not array).

Hope to hear from you soon,
Dmitry


TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0000069)
administrator (administrator)
2001-08-08 16:44

> 1. In contrast with what the manual says, "unique" attribute is not
> applicable to arrays and should be ignored (array is not l-value and cannot
> be equal to NULL).

You mean, unlike in the following C code? :-)

   void f(int x[])
   {
     x = NULL;
   }

More seriously: CamlIDL maps IDL arrays to C arrays when a
compile-time size is given (int data[10]), and to C pointers (to arrays)
otherwise (int data[]). This mimicks pretty much exactly what C does
with array function parameters.

> Currently incorrect C-code is generated:
>
> typedef struct
> {
> int len;
> [length_is(len),unique] char data[10];
> } Array1;

Yes, "unique" isn't applicable to arrays with a compile-time size.
Just don't do that :-) (I'll add code to detect this error.)

> 2. It's impossible to create bigarray of the fixed size -- pointer (not
> array) is always created:

Correct. I guess it should be possible to map them to C arrays when
all dimensions are known at compile-time. Or even when all dimensions
except the major one are known. I'll look into that.

> 3. Arrays of non-specified size are treated as pointers, but MIDL treats
> them differently:
> midl:
> typedef /* [public] */ struct __MIDL___MIDL_itf_array_0000_0002
> {
> int len;
> /* [length_is] */ int data[ 1 ];
> } Array3;

That's a lot more problematic. For one thing, this is not valid ANSI C --
more precisely, accessing an element of Array3.data beyond the 0-th
element results in undefined behavior. Yes, it usually works, but still.
Second, as you say:

> I would prefer the MIDL way, because otherwise we cannot properly describe
> C-structures where array (not pointer) is used, but its size is not
> known. Of course, these arrays can only be used as [in] parameters, and
> ML->C conversion functions should not be generated (if we need [out]
> structure, we should use pointer, not array).

The way CamlIDL is currently set up makes it very hard to have
conversions in only one direction. In particular, each struct
or typedef declaration must generate conversion functions in both
directions -- the code generated by CamlIDL is modular, in the sense
that conversions for named types are factored out as functions rather
than being expanded at point of use. Handling this properly would
require quite a lot of work...

- Xavier Leroy

(0000070)
administrator (administrator)
2001-08-08 18:00

A follow-up to my previous reply:

> 2. It's impossible to create bigarray of the fixed size -- pointer (not
> array) is always created:

A strong reason for doing this is that Caml bigarrays are designed so
that there is no data copying when converting between Caml and C.
This property can only be preserved if the bigarray is always
represented by a pointer in C -- if it's a C fixed-size array, some
copying is required. On the other hand, regular Caml arrays are
always copied between C and Caml. So, why is it that you'd need a
fixed-size bigarray -- isn't just an ordinary array sufficient?

- Xavier Leroy

(0000071)
administrator (administrator)
2001-08-29 15:52

Xavier Leroy <Xavier.Leroy@inria.fr> writes:

First of all, I apologize for the very long delay.

> > 1. In contrast with what the manual says, "unique" attribute is not
> > applicable to arrays and should be ignored (array is not l-value and cannot
> > be equal to NULL).
>
> You mean, unlike in the following C code? :-)
>
> void f(int x[])
> {
> x = NULL;
> }
>
> More seriously: CamlIDL maps IDL arrays to C arrays when a
> compile-time size is given (int data[10]), and to C pointers (to arrays)
> otherwise (int data[]). This mimicks pretty much exactly what C does
> with array function parameters.

For functions yes, but we are talking of structures. Obviously, C
structures have different memory layout for pointer and array fields.

> > Currently incorrect C-code is generated:
> >
> > typedef struct
> > {
> > int len;
> > [length_is(len),unique] char data[10];
> > } Array1;
>
> Yes, "unique" isn't applicable to arrays with a compile-time size.
> Just don't do that :-) (I'll add code to detect this error.)

OK.

> > 2. It's impossible to create bigarray of the fixed size -- pointer (not
> > array) is always created:
>
> Correct. I guess it should be possible to map them to C arrays when
> all dimensions are known at compile-time. Or even when all dimensions
> except the major one are known. I'll look into that.
>
> > 3. Arrays of non-specified size are treated as pointers, but MIDL treats
> > them differently:
> > midl:
> > typedef /* [public] */ struct __MIDL___MIDL_itf_array_0000_0002
> > {
> > int len;
> > /* [length_is] */ int data[ 1 ];
> > } Array3;
>
> That's a lot more problematic. For one thing, this is not valid ANSI C --
> more precisely, accessing an element of Array3.data beyond the 0-th
> element results in undefined behavior. Yes, it usually works, but still.

> Second, as you say:
>
> > I would prefer the MIDL way, because otherwise we cannot properly describe
> > C-structures where array (not pointer) is used, but its size is not
> > known. Of course, these arrays can only be used as [in] parameters, and
> > ML->C conversion functions should not be generated (if we need [out]
> > structure, we should use pointer, not array).
>
> The way CamlIDL is currently set up makes it very hard to have
> conversions in only one direction. In particular, each struct
> or typedef declaration must generate conversion functions in both
> directions -- the code generated by CamlIDL is modular, in the sense
> that conversions for named types are factored out as functions rather
> than being expanded at point of use. Handling this properly would
> require quite a lot of work...

Then we should prohibit using (int data[]) for now as non-supported
construct and force the user to use (int *data) in his/her code
instead. IMHO, implementing it different way than MIDL is simply not
acceptable -- we will easily have binary incompatibility under Windows in
that case.

And second, (int data[]) construct implemented as the data[1] array
sometimes is really useful. E.g., I do not know other way to define the
function like free(), taking a memory block with the header, indicating its
size.

Hope to hear from you soon,
Dmitry


(0000072)
administrator (administrator)
2001-08-29 15:58

Xavier Leroy <Xavier.Leroy@inria.fr> writes:

> > 2. It's impossible to create bigarray of the fixed size -- pointer (not
> > array) is always created:
>
> A strong reason for doing this is that Caml bigarrays are designed so
> that there is no data copying when converting between Caml and C.
> This property can only be preserved if the bigarray is always
> represented by a pointer in C -- if it's a C fixed-size array, some
> copying is required. On the other hand, regular Caml arrays are
> always copied between C and Caml. So, why is it that you'd need a
> fixed-size bigarray -- isn't just an ordinary array sufficient?

You are right. But it just means that

[bigarray] int data[something or empty];

should be prohibited and the "bigarray" attribute is applicable only to
pointers.

Hope to hear from you soon,
Dmitry



- Issue History
Date Modified Username Field Change
2005-11-18 10:13 administrator New Issue


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker