Jump to page: 1 2
Thread overview
Extern/scope issue
Apr 03, 2021
DLearner
Apr 03, 2021
rikki cattermole
Apr 03, 2021
DLearner
Apr 03, 2021
rikki cattermole
Apr 03, 2021
DLearner
Apr 03, 2021
rikki cattermole
Apr 03, 2021
DLearner
Apr 03, 2021
rikki cattermole
Apr 03, 2021
DLearner
Apr 03, 2021
rikki cattermole
Apr 03, 2021
ag0aep6g
Apr 03, 2021
DLearner
Apr 03, 2021
DLearner
Apr 03, 2021
z
Apr 03, 2021
DLearner
April 03, 2021

'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");
}

April 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");
> }
> 

April 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?
April 03, 2021
On 03/04/2021 11:17 PM, DLearner wrote:
> 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?

https://dlang.org/spec/attribute.html#gshared

However, you should be using the module system for accessing globals, rather than redeclaring them.
April 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
It seems that the whole extern keyword can be confusing with variables:

//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.)

April 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");
}

April 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

April 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");
}

April 04, 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).
April 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");
}

« First   ‹ Prev
1 2