Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

static variable issue

25 views
Skip to first unread message

sangitac...@gmail.com

unread,
Mar 18, 2017, 9:08:39 PM3/18/17
to
Hi,

I have one issue while using static variable. I have class dpst in my dynamic library, I am setting value for static variable in execute_before which is called inside library and in another function which is called from application I am reading its value. Unfortunately when I read value in updateShadowMemR from application it gives its value 0. I am not able to understand why? currAsync is class static variable which is read and set inside static function. Any help would be appreciated.

class dpst{

static Node * currAsync[MaxNumThreads];
public:

static void execute_before(THREADID threadid, void *arg1){. // called within a library
currAsync[threaid] = node;
}

static void updateShadowMemR(THREADID threadid, void *addr){. //called from application which uses this lib
std::cout<<"updateShadowMemR threadid "<<threadid<<" currAsync[threadid] "<<currAsync[threadid];
}
}

Alf P. Steinbach

unread,
Mar 18, 2017, 9:37:30 PM3/18/17
to
On 19-Mar-17 2:08 AM, sangitac...@gmail.com wrote:
> Hi,
>
> I have one issue while using static variable. I have class dpst in
> mydynamic library, I am setting value for static variable in
Static variables are zero-initialized before anything else.

This means that if your variable is never assigned, you will read a zero.

And likely that is what happens: at the time `updateShadowMemR` is
executed, the variable, or at least the specific item in that array, has
not yet been assigned.

The possible causes include

• general bug in the application logic,
• the static initialization order fiasco,
• thread synchronization issue.

You can find out more about what's going on by using a debugger, such as
the one in Visual Studio if you're on Windows.

An alternative or supplement is to use trace output.


Cheers & hth.,

- Alf

sangitac...@gmail.com

unread,
Mar 18, 2017, 11:51:05 PM3/18/17
to
Thanks, I have been using trace output and its so weird that I can see it has been set but in another function its not
#ExecuteBefore currAsync[8648] 0x212b5d0 //in execute_before
#updateShadowMemW currAsync[8648] 0 //in updateShadowMemR

sangitac...@gmail.com

unread,
Mar 18, 2017, 11:52:15 PM3/18/17
to
nothing else has been done with this variable between these calls.

Alf P. Steinbach

unread,
Mar 19, 2017, 12:39:44 AM3/19/17
to
On 19-Mar-17 4:52 AM, sangitac...@gmail.com wrote:
> On Saturday, March 18, 2017 at 11:51:05 PM UTC-4, sangitac...@gmail.com wrote:
>> On Saturday, March 18, 2017 at 9:37:30 PM UTC-4, Alf P. Steinbach wrote:
>>
>>> [snip]
>>> The possible causes include
>>>
>>> • general bug in the application logic,
>>> • the static initialization order fiasco,
>>> • thread synchronization issue.
>>>
>>> You can find out more about what's going on by using a debugger, such as
>>> the one in Visual Studio if you're on Windows.
>>>
>>> An alternative or supplement is to use trace output.
>>>
>>>
>>> Cheers & hth.,
>>>
>>> - Alf
>>
>> Thanks, I have been using trace output and its so weird that I can see it has been set but in another function its not
>> #ExecuteBefore currAsync[8648] 0x212b5d0 //in execute_before
>> #updateShadowMemW currAsync[8648] 0 //in updateShadowMemR
>
> nothing else has been done with this variable between these calls.

Well, there's one additional possible cause.

If this is in Windows, and hence your “dynamic library” is a DLL, then
dpst::currAsync in the DLL is not the same as dpst::currAsync in the
main application, unless it's exported – and I see no signs of that.

This is because Windows DLLs, unlike *nix shared libraries, are
separate, language independent entities with internal code and state.

The Window terminology is “module”. Each DLL and executable is a
“module”, and is represented as a PE (Portable Executable) format file.
Each module is defined by its imports and exports, which are designed to
be language independent: no support for C++ classes, so C++ compilers
have to fudge class exports and imports in various ways.

I don't think that problem is common in *nix-land, but I'm not very
familiar with *nix-land.


Cheers!,

- Alf

Paavo Helde

unread,
Mar 19, 2017, 4:14:02 AM3/19/17
to
As Alf said, it is indeed possible you have a case of "split
personality", i.e. there is not a single physical instance of the static
currAsync array as you think, but more. This might be caused by Windows
DLL peculiarities, but also for example if class dspt is actually a
class template and you instantiate it with slightly different types in
different places.

To fight with the DLL split:

1. Move all the functions accessing currAsync offline into a .cpp file
which is compiled only into a single DLL.

2. Fix all ensuing compiler and linker errors by adding needed
dllexport specifiers/macros and linker options.

3. Done.

In general, static variables should be best avoided as they do not scale
and cause a myriad of other problems. The client software should first
create an "engine" or "context" object via the special "init-library"
routine. This object would contain the data that was static before. The
client will pass the pointer to this object to all library functions
needing it (either as 'this' or as a normal parameter).

Voila, now the client has for example an ability to create two different
thread pools if it ever feels like so. As a bonus, the thing will work
regardless of the DLL boundary issues and static initialization order
fiascos.

sangitac...@gmail.com

unread,
Mar 19, 2017, 9:11:03 AM3/19/17
to
I am on linux using g++.

Paavo Helde

unread,
Mar 19, 2017, 9:36:52 AM3/19/17
to
On 19.03.2017 15:10, sangitac...@gmail.com wrote:
> On Sunday, March 19, 2017 at 4:14:02 AM UTC-4, Paavo Helde wrote:
>> On 19.03.2017 3:08, sangitac...@gmail.com wrote:
>>> Hi,
>>>
>>> I have one issue while using static variable. I have class dpst in my dynamic library, I am setting value for static variable in execute_before which is called inside library and in another function which is called from application I am reading its value. Unfortunately when I read value in updateShadowMemR from application it gives its value 0. I am not able to understand why? currAsync is class static variable which is read and set inside static function. Any help would be appreciated.

>> As Alf said, it is indeed possible you have a case of "split
>> personality", i.e. there is not a single physical instance of the static
>> currAsync array as you think, but more. This might be caused by Windows
>> DLL peculiarities, but also for example if class dspt is actually a
>> class template and you instantiate it with slightly different types in
>> different places.
>
>
> I am on linux using g++.

Then you have a more interesting bug. For debugging you can print out
the address of the array itself, then it becomes clear whether this is
physically the same array or not. If same, then put a data breakpoint
there after assigning thenon-zero value; this will be triggered if/when
the value unexpectedly goes back to zero.

My general suggestion to avoid mutable static variables still holds.





sangitac...@gmail.com

unread,
Mar 19, 2017, 9:50:24 AM3/19/17
to
You are right, there are two different instances of same static variable, I am getting different address, but I am wondering why this is the case.

Paavo Helde

unread,
Mar 19, 2017, 9:57:48 AM3/19/17
to
On 19.03.2017 15:50, sangitac...@gmail.com wrote:
>>>> On 19.03.2017 3:08, sangitac...@gmail.com wrote:
>>>>> I have one issue while using static variable. I have class dpst in my dynamic library, I am setting value for static variable in execute_before which is called inside library and in another function which is called from application I am reading its value. Unfortunately when I read value in updateShadowMemR from application it gives its value 0. I am not able to understand why? currAsync is class static variable which is read and set inside static function. Any help would be appreciated.
>
> You are right, there are two different instances of same static variable, I am getting different address, but I am wondering why this is the case.

And this is not a template class?

sangitac...@gmail.com

unread,
Mar 19, 2017, 10:02:06 AM3/19/17
to
No, its not.

Paavo Helde

unread,
Mar 19, 2017, 10:09:59 AM3/19/17
to
Ok, but is the class definition fully inline (present in the header file)?





Paavo Helde

unread,
Mar 19, 2017, 10:26:47 AM3/19/17
to
I mean, the definition of the static array must be placed outside of the
class definition itself. In which file is this static array definition?
Is this file compiled only into the shared library?

sangitac...@gmail.com

unread,
Mar 19, 2017, 11:42:14 AM3/19/17
to
I have taken care of that but I just worked around and removed all static variables but this will keep me puzzled as I did not expect static variable having two instances based on how it has been invoked.
Thank you so much for your help.

Paavo Helde

unread,
Mar 19, 2017, 12:17:23 PM3/19/17
to
On 19.03.2017 17:42, sangitac...@gmail.com wrote:

>
> I have taken care of that but I just worked around and removed all static variables but this will keep me puzzled as I did not expect static variable having two instances based on how it has been invoked.

The Linux/gcc linking model should avoid such things AFAIK, the symbol
visibility used by the dynamic linker is designed to mimic the standard
static library model, by default. It is possible to create a shared
library which has some or most symbols hidden, in which case it would be
indeed possible to have duplicate symbols in different libraries. But I
am no expert here, at the intertubes it seems they recommend to learn

https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf

Anyway, it is a Good Thing you got rid of the globals!
0 new messages