digitalmars.D.learn - Extern/scope issue
- DLearner (28/28) Apr 03 2021 'Testmain' imports module 'testmod'.
- rikki cattermole (5/43) Apr 03 2021 That is a regular variable.
- DLearner (3/12) Apr 03 2021 Does this mean D has no equivalent of C globals?
- rikki cattermole (4/21) Apr 03 2021 https://dlang.org/spec/attribute.html#gshared
- DLearner (23/23) Apr 03 2021 Tried the following, same result (1,0,2,1):
- rikki cattermole (19/19) Apr 03 2021 --- main.d
- DLearner (26/30) Apr 03 2021 Solved:
- rikki cattermole (3/5) Apr 03 2021 extern(D) sets the ABI AND mangling.
- DLearner (4/10) Apr 03 2021 I'm sure you are correct, but extern(C) -> extern(D) in both
- rikki cattermole (2/14) Apr 03 2021 https://dlang.org/spec/abi.html#name_mangling
- ag0aep6g (26/34) Apr 03 2021 With `extern (C)`, those two `xvar`s refer to the same data.
- DLearner (27/63) Apr 03 2021 Thank you, your suggestions worked.
- DLearner (21/24) Apr 03 2021 If the module system is dumped, and evrything put into one file,
- z (29/31) Apr 03 2021 With __gshared.
- DLearner (4/18) Apr 03 2021 I tried case 4, failed with link errors.
'Testmain' imports module 'testmod'. Both are shown below. I expected 1,1,2,2. I got 1,0,2,1 - which speaks to scope/extern misunderstanding Any ideas? Best regards Testmain: int xvar; import testmod; void main() { import std.stdio; writeln("Entering: main"); xvar = 1; writeln("xvar=", xvar); testsub(); writeln("xvar=", xvar); writeln("Leaving: main"); } Testmod: void testsub() { extern(D) int xvar; import std.stdio; writeln("Entering: testsub"); writeln("xvar=", xvar); xvar = 2; writeln("xvar=", xvar); writeln("Leaving: testsub"); }
Apr 03 2021
On 03/04/2021 11:01 PM, DLearner wrote:'Testmain' imports module 'testmod'. Both are shown below. I expected 1,1,2,2. I got 1,0,2,1 - which speaks to scope/extern misunderstanding Any ideas? Best regards Testmain: int xvar;TLS variable with D mangling, not a c global.import testmod; void main() { import std.stdio; writeln("Entering: main"); xvar = 1; writeln("xvar=", xvar); testsub(); writeln("xvar=", xvar); writeln("Leaving: main"); } Testmod: void testsub() { extern(D) int xvar;That is a regular variable. Setting the calling convention/mangling like that doesn't make any sense and shouldn't be allowed in context.import std.stdio; writeln("Entering: testsub"); writeln("xvar=", xvar); xvar = 2; writeln("xvar=", xvar); writeln("Leaving: testsub"); }
Apr 03 2021
On Saturday, 3 April 2021 at 10:05:45 UTC, rikki cattermole wrote:On 03/04/2021 11:01 PM, DLearner wrote:[...]TLS variable with D mangling, not a c global.[...]That is a regular variable. Setting the calling convention/mangling like that doesn't make any sense and shouldn't be allowed in context.[...]TLS variable with D mangling, not a c global.Does this mean D has no equivalent of C globals? What is the D way of doing this?
Apr 03 2021
On 03/04/2021 11:17 PM, DLearner wrote:On Saturday, 3 April 2021 at 10:05:45 UTC, rikki cattermole wrote:https://dlang.org/spec/attribute.html#gshared However, you should be using the module system for accessing globals, rather than redeclaring them.On 03/04/2021 11:01 PM, DLearner wrote:[...]TLS variable with D mangling, not a c global.[...]That is a regular variable. Setting the calling convention/mangling like that doesn't make any sense and shouldn't be allowed in context.[...]TLS variable with D mangling, not a c global.Does this mean D has no equivalent of C globals? What is the D way of doing this?
Apr 03 2021
Tried the following, same result (1,0,2,1): testmain: __gshared int xvar; import testmod; void main() { import std.stdio; writeln("Entering: main"); xvar = 1; writeln("xvar=", xvar); testsub(); writeln("xvar=", xvar); writeln("Leaving: main"); } testmod: void testsub() { __gshared int xvar; import std.stdio; writeln("Entering: testsub"); writeln("xvar=", xvar); xvar = 2; writeln("xvar=", xvar); writeln("Leaving: testsub"); }
Apr 03 2021
--- main.d module main; extern(C) __gshared int foo; import std; void main() { import foo : func; func; writeln(foo); } --- foo.d module foo; extern extern(C) __gshared int foo; void func() { foo++; } The __gshared is irrelevant to it working between modules, but it is relevant if you want C compatibility between threads (NOTE: extern(C) sets mangling, otherwise the module would be encoded in its name).
Apr 03 2021
The __gshared is irrelevant to it working between modules, but it is relevant if you want C compatibility between threads (NOTE: extern(C) sets mangling, otherwise the module would be encoded in its name).Solved: The following produces the expected result. However, changing extern(C) to extern(D) causes linker failures. To me, that is bizarre. Testmain: extern(C) int xvar; import testmod; void main() { import std.stdio; writeln("Entering: main"); xvar = 1; writeln("xvar=", xvar); testsub(); writeln("xvar=", xvar); writeln("Leaving: main"); } Testmod: extern extern(C) int xvar; void testsub() { import std.stdio; writeln("Entering: testsub"); writeln("xvar=", xvar); xvar = 2; writeln("xvar=", xvar); writeln("Leaving: testsub"); }
Apr 03 2021
On 04/04/2021 2:34 AM, DLearner wrote:However, changing extern(C) to extern(D) causes linker failures. To me, that is bizarre.extern(D) sets the ABI AND mangling. D mangling incorporates things like the module name.
Apr 03 2021
On Saturday, 3 April 2021 at 13:38:25 UTC, rikki cattermole wrote:On 04/04/2021 2:34 AM, DLearner wrote:I'm sure you are correct, but extern(C) -> extern(D) in both references. So both source streams are aware of the convention used.However, changing extern(C) to extern(D) causes linker failures. To me, that is bizarre.extern(D) sets the ABI AND mangling. D mangling incorporates things like the module name.
Apr 03 2021
On 04/04/2021 2:48 AM, DLearner wrote:On Saturday, 3 April 2021 at 13:38:25 UTC, rikki cattermole wrote:https://dlang.org/spec/abi.html#name_manglingOn 04/04/2021 2:34 AM, DLearner wrote:I'm sure you are correct, but extern(C) -> extern(D) in both references. So both source streams are aware of the convention used.However, changing extern(C) to extern(D) causes linker failures. To me, that is bizarre.extern(D) sets the ABI AND mangling. D mangling incorporates things like the module name.
Apr 03 2021
On 03.04.21 15:34, DLearner wrote:The following produces the expected result. However, changing extern(C) to extern(D) causes linker failures. To me, that is bizarre. Testmain: extern(C) int xvar;[...]Testmod: extern extern(C) int xvar;With `extern (C)`, those two `xvar`s refer to the same data. Without `extern (C)` (or with `extern (D)`), they are distinct variables with no relation to another. In D, you don't re-declare another module's symbols. You import the other module. ---- module testmain; import std.stdio: writeln; import testmod: testsub, xvar; void main() { xvar = 1; writeln(xvar); /* prints "1" */ testsub(); writeln(xvar); /* prints "2" */ } ---- ---- module testmod; int xvar; /* same as `extern (D) int xvar;` */ void testsub() { xvar = 2; } ----
Apr 03 2021
On Saturday, 3 April 2021 at 13:50:27 UTC, ag0aep6g wrote:On 03.04.21 15:34, DLearner wrote:Thank you, your suggestions worked. No externs anywhere. For the record, the code is below. import itf; import testmod:testsub; void main() { import std.stdio; writeln("Entering: main"); xvar = 1; writeln("xvar=", xvar); testsub(); writeln("xvar=", xvar); writeln("Leaving: main"); } module itf; int xvar; module testmod; import itf; void testsub() { import std.stdio; writeln("Entering: testsub"); writeln("xvar=", xvar); xvar = 2; writeln("xvar=", xvar); writeln("Leaving: testsub"); }The following produces the expected result. However, changing extern(C) to extern(D) causes linker failures. To me, that is bizarre. Testmain: extern(C) int xvar;[...]Testmod: extern extern(C) int xvar;With `extern (C)`, those two `xvar`s refer to the same data. Without `extern (C)` (or with `extern (D)`), they are distinct variables with no relation to another. In D, you don't re-declare another module's symbols. You import the other module. ---- module testmain; import std.stdio: writeln; import testmod: testsub, xvar; void main() { xvar = 1; writeln(xvar); /* prints "1" */ testsub(); writeln(xvar); /* prints "2" */ } ---- ---- module testmod; int xvar; /* same as `extern (D) int xvar;` */ void testsub() { xvar = 2; } ----
Apr 03 2021
https://dlang.org/spec/attribute.html#gshared However, you should be using the module system for accessing globals, rather than redeclaring them.If the module system is dumped, and evrything put into one file, works perfectly. With or without __gshared in from of 'int xvar'. int xvar; void main() { import std.stdio; writeln("Entering: main"); xvar = 1; writeln("xvar=", xvar); testsub(); writeln("xvar=", xvar); writeln("Leaving: main"); } void testsub() { import std.stdio; writeln("Entering: testsub"); writeln("xvar=", xvar); xvar = 2; writeln("xvar=", xvar); writeln("Leaving: testsub"); }
Apr 03 2021
On Saturday, 3 April 2021 at 10:17:14 UTC, DLearner wrote:Does this mean D has no equivalent of C globals? What is the D way of doing this?With __gshared. If the global is defined from within another language, apparently you'd have to do [extern(C) extern __gshared *name*](https://dlang.org/spec/interfaceToC.html#c-globals) It seems that the whole extern keyword can be confusing with variables: ```d //L is the language name extern(L) returnType functionName(parameters); // function implemented in another language or out of this module. extern(L) returnType functionName(parameters) {/*...*/}//extern only changes the name mangling and the calling rules in the resulting assembly code.(with D it does not change anything?) extern(L) variableType variableName; //what you did, declares a normal variable, except that the name mangling rule is that of the language you specified. extern(L) extern otherQualifiersIfAny variableType variableName; //appears to be a variable declared outside of the module, so at link time a .obj file will have to declare a variable with this symbol name or else the linker will error out. ``` It seems that case 4 is what you desired but i do not know if with this module hierarchy it can/will work with dub.(it should.) With the code as is you should be able to access both variables from main with `testmod.xvar` and simply `xvar`.(when name conflicts like this occur the most local is used by default, otherwise use the full name which should be `testmain.xvar` in this case.)
Apr 03 2021
extern(L) extern otherQualifiersIfAny variableType variableName; //appears to be a variable declared outside of the module, so at link time a .obj file will have to declare a variable with this symbol name or else the linker will error out. ``` It seems that case 4 is what you desired but i do not know if with this module hierarchy it can/will work with dub.(it should.) With the code as is you should be able to access both variables from main with `testmod.xvar` and simply `xvar`.(when name conflicts like this occur the most local is used by default, otherwise use the full name which should be `testmain.xvar` in this case.)I tried case 4, failed with link errors. I am not trying to establish two variables, just exactly the same one everywhere. That's why the desired test output is 1,1,2,2
Apr 03 2021