Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dstep not converting const T x[] to const (T)* x #85

Closed
dataPulverizer opened this issue Aug 5, 2016 · 23 comments
Closed

dstep not converting const T x[] to const (T)* x #85

dataPulverizer opened this issue Aug 5, 2016 · 23 comments

Comments

@dataPulverizer
Copy link

I am currently working with dstep version 0.2.2 and found that: const T x[] is not currently being converted to const (T)* x. It says <unimplemented>. I am currently doing a find and replace to const T *x in the original script which gives the desired output but it would be nice not to have to do that.

Thanks a lot for this very useful tool.

@ciechowoj
Copy link
Contributor

ciechowoj commented Aug 5, 2016

Could you give an example that reproduces this bug? E.g. a code snippet with the problematic types?

@dataPulverizer
Copy link
Author

An example is converting a function like this:

int gsl_dft_complex_forward (const double data[], const size_t stride, const size_t n, double result[]);

The output you get is this:

int gsl_dft_complex_forward (<unimplemented> data, const size_t stride, const size_t n, <unimplemented> result);

@mihails-strasuns
Copy link
Contributor

Works for me on master. Very likely that I have accientally fixed it as a side effect of a35b6ea

@ciechowoj
Copy link
Contributor

Works for me on master. Very likely that I have accientally fixed it as a side effect of a35b6ea

On master it converts:

int func (const double data[], double result[]);

to

int func (const double[] data, double[] result);

@Dicebot, @dataPulverizer
Is it correct? Shouldn't it convert the C-arrays to pointers. I suppose D-arrays are slightly different, as there is a way to get the length of the array...

@jacob-carlborg
Copy link
Owner

@ciechowoj, yes I think it needs to translate the C arrays to pointers. A D array is twice as large as a pointer (the extra length as you mentioned).

@mihails-strasuns
Copy link
Contributor

@ciechowoj
Copy link
Contributor

@jacob-carlborg

I'm trying to fix this, don't you know what the following comment from dstep/translatorType.d means?

        // extern static arrays (which are normally present in bindings)
        // have same ABI as extern dynamic arrays, size is only checked
        // against declaration in header. As it is not possible in D
        // to define static array with ABI of dynamic one, only way is to
        // abandon the size information
        return elementType ~ "[]";

@mihails-strasuns
Copy link
Contributor

It is an old comment from me and I think it is wrong - I didn't know at the time of writing it that ref T[42] will use same ABI as T[42] in C. Of course it likely should have used * instead of [] anyway as mentioned by @jacob-carlborg

@mihails-strasuns
Copy link
Contributor

(but original use case I had was for global extern variables, not for function parameters - please check if ABI is different there)

@ciechowoj
Copy link
Contributor

ciechowoj commented Aug 9, 2016

Hmm, I do not know at the moment how to check it other way than experimentally.
Compiled with gcc -c lib.c && dmd test.d lib.o && ./test

// lib.c

const int tab[] = {
    42,
    42,
    24
};

Segmentation fault.

//  test.d

extern (C) extern __gshared const (int)[] tab;

int main()
{
    import std.stdio;

    writeln(tab[0]);

    return 0;
}

Segmentation fault.

//  test.d

extern (C) extern __gshared const (int)* tab;

int main()
{
    import std.stdio;

    writeln(tab[0]);

    return 0;
}

42

//  test.d

extern (C) extern __gshared const (int)[3] tab;

int main()
{
    import std.stdio;

    writeln(tab[0]);

    return 0;
}

It seems like the only way to translate this is to compute the size of an array somehow during translation...

@ciechowoj
Copy link
Contributor

Hmm, worse if the array is declared with extern already in the header file...

extern const int tab[];

ciechowoj added a commit to ciechowoj/dstep that referenced this issue Aug 9, 2016
ciechowoj added a commit to ciechowoj/dstep that referenced this issue Aug 9, 2016
@ciechowoj
Copy link
Contributor

On forum.dlang they suggested to declare an one element array instead.

https://forum.dlang.org/post/nocnnd$oop$1@digitalmars.com

@jacob-carlborg
Copy link
Owner

What if you make it a pointer?

jacob-carlborg added a commit that referenced this issue Aug 9, 2016
Fix #85: dstep not converting `const T x[]` to `const (T)* x`.
@dataPulverizer
Copy link
Author

Sorry for my silence on this I think the conversion const T[] to const (T)* x is the right thing to do. The Case of the global variable is an edge case that should probably be put in the readme file to make users aware of this issue. Anyway global variables like that are seriously NASTY!

@ciechowoj
Copy link
Contributor

ciechowoj commented Aug 9, 2016

What if you make it a pointer?

Segmentation fault.

//  test.d

extern (C) extern __gshared const (int)* tab;

int main()
{
    import std.stdio;

    writeln(tab[0]);

    return 0;
}

@mihails-strasuns
Copy link
Contributor

Hm, how about extern (C) extern __gshared const int[0] tab? With some luck it may behave thesame as variadic length struct trick.

@ciechowoj
Copy link
Contributor

Hm, how about extern (C) extern __gshared const int[0] tab? With some luck it may behave the same as variadic length struct trick.

dmd will not allow you to access directly, statically checking bounds, warning that the array is too short. On the forum I got an advice to use length 1, but there is the same issue with element access. The workaround is to use .ptr for indexing, e.g. tab.ptr[42].

@ciechowoj
Copy link
Contributor

I suppose we could fix it for the time being by declaring an array with 0 or 1 length.

@dataPulverizer
Copy link
Author

Is this something that needs fixing in D itself? Is the inability to consistently allow the replacement of const T x[] with const (T)* x not a bug?

@jacob-carlborg
Copy link
Owner

@dataPulverizer sounds like a bug to me.

@ciechowoj
Copy link
Contributor

ciechowoj commented Aug 10, 2016

Is this something that needs fixing in D itself? Is the inability to consistently allow the replacement of const T x[] with const (T)* x not a bug?

@dataPulverizer sounds like a bug to me.

Just for curiosity, do you have an idea how it could be correctly solved/handled in D?

@dataPulverizer
Copy link
Author

@ciechowoj nothing at all comes to mind

@jacob-carlborg
Copy link
Owner

Not sure if it's related. On OS X, DMD outputs the extern variable to __textcoal_nt section while compiling the C code, Clang outputs the extern variable to the __text section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants