| Thread overview | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 08, 2014 Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
When upgrading my compiler from 2.065 to 2.066.1 I have encountered problems with some of my extern(C) code.
My declarations (in a .di file) are wrapped in an extern(C) declaration. The code compiled fine in 2.065. In 2.066.1 it first complained about functions returning "const char *" ("function without this cannot be const"). After removing the offending consts, it now complains of a missing "init" field of a struct.
It looks like its trying to access the stuff as D code rather than C code. Can anyone shed some light on what the problem might be?
Thanks in advance
Jason
| ||||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason den Dulk | On Saturday, 8 November 2014 at 10:03:51 UTC, Jason den Dulk wrote:
> When upgrading my compiler from 2.065 to 2.066.1 I have encountered problems with some of my extern(C) code.
>
> My declarations (in a .di file) are wrapped in an extern(C) declaration. The code compiled fine in 2.065. In 2.066.1 it first complained about functions returning "const char *" ("function without this cannot be const").
const char* foo() {}
is a function that takes a const 'this' reference and returns char*
You want
const(char)* foo() {}
or
const(char*) foo() {}
If you do want a const 'this' then you should write:
char* foo() const {}
| |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason den Dulk | On Saturday, 8 November 2014 at 10:03:51 UTC, Jason den Dulk wrote:
> When upgrading my compiler from 2.065 to 2.066.1 I have encountered problems with some of my extern(C) code.
>
> My declarations (in a .di file) are wrapped in an extern(C) declaration. The code compiled fine in 2.065. In 2.066.1 it first complained about functions returning "const char *" ("function without this cannot be const"). After removing the offending consts, it now complains of a missing "init" field of a struct.
>
> It looks like its trying to access the stuff as D code rather than C code. Can anyone shed some light on what the problem might be?
>
> Thanks in advance
> Jason
This is highlighting the problem that using const in a function declaration can lead to confusion. Look at this example:
const char* foo()
Here const is interpreted as an attribute of the function not the char type. So defining it as a type constructor will remove the confusion like this:
const(char)* foo()
Here we are declaring a pointer to a const char which is (if you're interfacing with C) what you want. I'm assuming the compiler is being more strict about this now?
There was a forum thread somewhere detailing a proposition to only accept function attributes on the right of the declaration to avoid this confusion but i think it was just thoughts.
Have you got an example of the struct giving you problems?
| |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason den Dulk | On 11/8/2014 7:03 PM, Jason den Dulk wrote:
>
> It looks like its trying to access the stuff as D code rather than C
> code. Can anyone shed some light on what the problem might be?
Anything in an extern(C) block *is* D code. The extern(C) bit just affects the name mangling.
| |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On 11/8/2014 8:43 PM, Mike Parker wrote:
> On 11/8/2014 7:03 PM, Jason den Dulk wrote:
>
>>
>> It looks like its trying to access the stuff as D code rather than C
>> code. Can anyone shed some light on what the problem might be?
>
> Anything in an extern(C) block *is* D code. The extern(C) bit just
> affects the name mangling.
>
And the calling convention for functions, actually.
| |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | On Saturday, 8 November 2014 at 10:52:16 UTC, Gary Willoughby wrote: > const(char)* foo() This fixed the const issue. Thanks for that guys. > Have you got an example of the struct giving you problems? struct st_mysql_res { my_ulonglong row_count; MYSQL_FIELD *fields; MYSQL_DATA *data; MYSQL_ROWS *data_cursor; ulong *lengths; /* column lengths of current row */ MYSQL *handle; /* for unbuffered reads */ st_mysql_methods *methods; MYSQL_ROW row; /* If unbuffered read */ MYSQL_ROW current_row; /* buffer to current row */ MEM_ROOT field_alloc; uint field_count, current_field; my_bool eof; /* Used by mysql_fetch_row */ /* mysql_stmt_close() had to cancel this result */ my_bool unbuffered_fetch_cancelled; void *extension; } The struct is never instantised anywhere. It is always referenced by pointer. The error message is: undefined reference to `_D6jaypha5dbsql5mysql1c5mysql12st_mysql_res6__initZ' A search of the raw object file generated produces the above reference, however when disassembling the file, it disappears. Not sure what the significance of that is. | |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason den Dulk | Some extra insight. In the struct "my_bool" is a char alias. I change it to a byte, it compiles. I change it back to char, it dies. | |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason den Dulk | On 11/8/14 5:03 AM, Jason den Dulk wrote:
> My declarations (in a .di file) are wrapped in an extern(C) declaration.
> The code compiled fine in 2.065. In 2.066.1 it first complained about
> functions returning "const char *" ("function without this cannot be
> const").
BTW, the code as compiled in 2.065 was returning char *, not const char *. So the new compiler fixed a bug in your code :)
-Steve
| |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason den Dulk | "Jason den Dulk" wrote in message news:mobvaeuhbjujojfaycgn@forum.dlang.org... > Some extra insight. > > In the struct "my_bool" is a char alias. I change it to a byte, it compiles. I change it back to char, it dies. This symbol (`_D6jaypha5dbsql5mysql1c5mysql12st_mysql_res6__initZ') is the init data for the struct. D's char's default value is 0xFF. When structs can be initialized by memsetting to zero, they don't need an init symbol. So you have a few options: - Don't use char, use something like bool or ubyte that has 0 as the default value. When interfacing with C you only need to match size (and sometimes sign) for C's integral types. - Give the struct member a default value of false - Compile the .di file like you do the rest of your source, so the init symbol gets found correctly. | |||
November 08, 2014 Re: Interfacing with C in 2.066.1 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | Or when you declare an instance of the variable, disable auto-initialization via "=void", then do a memset(0). | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply