extern __gshared const(char)* symbol fails

Steven Schveighoffer schveiguy at gmail.com
Fri Aug 31 17:50:17 UTC 2018


On 8/31/18 2:20 AM, James Blachly wrote:
> Hi all,
> 
> I am linking to a C library which defines a symbol,
> 
> const char seq_nt16_str[] = "=ACMGRSVTWYHKDBN";
> 
> In the C sources, this is an array of 16 bytes (17 I guess, because it 
> is written as a string).
> 
> In the C headers, it is listed as extern const char seq_nt16_str[];
> 
> When linking to this library from another C program, I am able to treat 
> seq_nt16_str as any other array, and being defined as [] fundamentally 
> it is a pointer.
> 
> When linking to this library from D, I have declared it as:
> 
> extern __gshared const(char)* seq_nt16_str;
> 
> ***But this segfaults when I treat it like an array (e.g. by accessing 
> members by index).***
> 
> Because I know the length, I can instead declare:
> 
> extern __gshared const(char)[16] seq_nt16_str;
> 
> My question is: Why can I not treat it opaquely and use it declared as 
> char* ? Does this have anything to do with it being a global stored in 
> the static data segment?
> 

What the C compiler is doing is storing it as data, and then storing the 
symbol to point at the first element in the data.

When you use const char* in D, it's expecting a *pointer* to be stored 
at that address, not the data itself. So using it means segfault. The 
static array is the correct translation, even though it leaks 
implementation details.

In C, it's working because C has the notion of a symbol being where an 
array starts. D has no concept of a C array like that, every array must 
have a length. So there is no equivalent you can use in D -- you have to 
supply the length.

Alternatively, you can treat it as a const char:

extern(C) extern const(char) seq_nt16_str;

void main()
{
    import core.stdc.stdio;
    printf("%s\n", &seq_nt16_str); // should print the string
}

You could wrap it like this:

pragma(mangle, "seq_nt16_str");
private extern(C) extern const(char) _seq_nt16_str_STORAGE;

@property const(char)* seq_nt16_str()
{
    return &_seq_nt16_str_STORAGE;
}

To make the code look similar.

-Steve


More information about the Digitalmars-d-learn mailing list