digitalmars.D.learn - DMD: can't get extern __gshared to work right (vs. LDC)
- DanielG (28/28) Feb 06 2019 macOS 12, DMD 2.084.0 / LDC 1.14.0-beta1
- DanielG (9/9) Feb 07 2019 Follow-up:
- Kagamin (4/5) Feb 07 2019 It's correct for Windows: address of imported data is not known
- DanielG (5/6) Feb 08 2019 I created a minimal example and it definitely segfaults at
- rikki cattermole (2/10) Feb 08 2019 File, inconsistent behavior is inconsistent. Not good.
- DanielG (3/4) Feb 08 2019 done: https://issues.dlang.org/show_bug.cgi?id=19660
- DanielG (13/13) Feb 18 2019 In the meantime, while I'm waiting for this bug to be noticed by
- rikki cattermole (6/23) Feb 18 2019 Because you need two different versions to choose between them, either
macOS 12, DMD 2.084.0 / LDC 1.14.0-beta1 I have a C API that exports some global variables, declared like so: .h file: ===== extern "C" { #define PUBLIC_API __attribute__((visibility("default"))) struct __opaqueHandle; typedef __opaqueHandle* opaqueHandle_t; PUBLIC_API extern const opaqueHandle_t kSomeGlobalValue; } .cpp file: ====== const opaqueHandle_t kSomeGlobalValue = (opaqueHandle_t) kSomeInternalPointer; .d file: ==== extern (C): export extern __gshared opaqueHandle_t kSomeGlobalValue; I have no issues linking against the resulting .dylib with a C/C++ program, nor issues with DMD on Windows with the same code. However with DMD on macOS, the value is coming through incorrectly. It looks like a valid pointer value (vs. pure garbage), but it's still incorrect. LDC2 works fine, no issues. Is there some extra flag I need to pass to DMD on Mac to get it to see this global properly? It links fine, no errors, but the value is still wrong. I should also mention that this dylib exports functions, too, and they are working fine even with DMD. It's just the globals I'm having problems with.
Feb 06 2019
Follow-up: The problem on DMD macOS is the "export" keyword. It ended up in my code during a similar-ish problem last year, when I was having trouble linking against DLL global variables on Windows. If I remove the "export" keyword in the D interface, it will work on macOS but break on Windows. (To reiterate: WITHOUT "export" on Windows, it refuses to link. WITH "export" on Mac, it seems to link but with incorrect results) Is this correct behavior?
Feb 07 2019
On Friday, 8 February 2019 at 05:28:30 UTC, DanielG wrote:Is this correct behavior?It's correct for Windows: address of imported data is not known at link time and must use dynamic linkage. AFAIK, export attribute doesn't do much on posix platforms.
Feb 07 2019
On Friday, 8 February 2019 at 07:52:26 UTC, Kagamin wrote:AFAIK, export attribute doesn't do much on posix platforms.I created a minimal example and it definitely segfaults at runtime in the presence of "export" (on Mac, haven't tested linux). So it's required for Windows and silently evil for Mac... Any reason I shouldn't file a DMD bug for this?
Feb 08 2019
On 08/02/2019 9:14 PM, DanielG wrote:On Friday, 8 February 2019 at 07:52:26 UTC, Kagamin wrote:File, inconsistent behavior is inconsistent. Not good.AFAIK, export attribute doesn't do much on posix platforms.I created a minimal example and it definitely segfaults at runtime in the presence of "export" (on Mac, haven't tested linux). So it's required for Windows and silently evil for Mac... Any reason I shouldn't file a DMD bug for this?
Feb 08 2019
On Friday, 8 February 2019 at 09:19:12 UTC, rikki cattermole wrote:File, inconsistent behavior is inconsistent. Not good.done: https://issues.dlang.org/show_bug.cgi?id=19660
Feb 08 2019
In the meantime, while I'm waiting for this bug to be noticed by anybody with the skills to address it, what would be the most elegant way of working around it? Obviously I could do a: version(Windows) { export extern __gshared ... } else { extern __gshared ... } But what's the minimal way of toggling the presence of "export" in a declaration? Using mixins feels kind of gross for this, but if that's the only option ... Almost makes me long for the C preprocessor :P
Feb 18 2019
On 19/02/2019 6:26 AM, DanielG wrote:In the meantime, while I'm waiting for this bug to be noticed by anybody with the skills to address it, what would be the most elegant way of working around it? Obviously I could do a: version(Windows) { export extern __gshared ... } else { extern __gshared ... } But what's the minimal way of toggling the presence of "export" in a declaration? Using mixins feels kind of gross for this, but if that's the only option ... Almost makes me long for the C preprocessor :PBecause you need two different versions to choose between them, either set a per module version or use static if with enum's. But yeah, I would do that. Of course a mixin template with a code string (q{ ... }) would be cleaner. After all, ``export { mixin(str); }`` would work well.
Feb 18 2019