KenC
KenC

Reputation: 127

function doesn't have volatile. How to fix?

I am sharing a variable between 2 threads. And I use volatile to avoid the optimization.

However, It shows an error for not having volatile in strcpy. (as below)

How could I fix this error properly?

Some guy told me to type-cast away volatile. But if I cast away volatile, then I lost the purpose of volatile.... and end up might get a runtime error from being optimized..... isn't it?

Thank a lot.

(the code can be compiled directly)


CRITICAL_SECTION CriticalSection;

HANDLE hEvent;

void __cdecl MyThread(void* name)

{

char serName[256];

volatile char* vptr = (char*) name;



EnterCriticalSection(&CriticalSection);



strcpy(serName, vptr); // error : cannot convert 'volatile'

// use (and not modify) name…



LeaveCriticalSection(&CriticalSection);

SetEvent (hEvent) ;

}




void main ()

{

char name[256] = "abcde";

hEvent = CreateEvent (NULL, false, false, NULL) ;

if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400) )

return;



_beginthread (MyThread, 0, name) ;



EnterCriticalSection(&CriticalSection);

// access name…

LeaveCriticalSection(&CriticalSection);



WaitForSingleObject (hEvent, INFINITE) ;

DeleteCriticalSection(&CriticalSection);

CloseHandle (hEvent);

system("pause");

}

In the other hand, I can write my own strcpy to support volatile. But this is weird. because if so, then I have to write my own I/O stream (or those complicated functions) every time I use volatile?

Thx a again for answering.

Upvotes: 5

Views: 559

Answers (2)

6502
6502

Reputation: 114519

Apparently you don't have a clear understanding of what "volatile" means. The meaning is more or less "Hey compiler, please note that someone else will be changing this variable so you cannot assume that unless your code writes it the value will remain constant. Moreover someone else may be watching at this variable so when I write to this variable please don't do strange thing with the assumption that doesn't matter because for those other guys watching it matters, so just write what I want you to write and when I tell you to do so."

When is important to use "volatile? Here is a common example:

volatile int stopflag; // flag will be set by an interrupt handler

void mainloop()
{
    stopflag = 0;
    while (!stopflag)
    {
       ...
    }
}

If the code in the three dots never touches stopflag and never calls a function with an unknown implementation then the compiler could be tempted to avoid reading the flag in the loop because looking at the code itself it would seem that there is no need to read the variable at all... just set and loop forever.

Another case could be:

extern volatile unsigned char outloc; // monitored by hardware

...
// emit a wave pulse
for (int x=0; x<256; x++)
    outloc = x;

Here without volatile the compiler could be tempted to just write 0xFF to the location instead of writing all intermediate values.

Please note that using volatile for thread synchronization on modern hardware is insufficient. In today computers normally the CPU is multicore and so writes and reads are not atomic operation any more. While in the past (on single-core CPUs) it was in practice often possible to use volatile variables for thread synchronization now this is false.

You seem indeed interested in telling that the buffer is indeed being read and written by others, but in this case the address of the buffer is public so at any call of a function (unless it's inlined or has a known implementation code) the compiler must assume that the buffer content has possibly changed or will be read by unknown code.

I'd bet that thread synchronization primitives are declared in a proper way to ensure that this is also true in your case (even if strcpy is inlined).

Upvotes: 4

jsist
jsist

Reputation: 5253

I can understand, at some places (while using threads) we don't want optimization to happen and for that we use "volatile" keyword.

Refer MSDN for

To declare the object pointed to by the pointer as const or volatile, use a declaration of the form:

const    char *cpch;
volatile char *vpch;

To declare the value of the pointer — that is, the actual address stored in the pointer — as const or volatile, use a declaration of the form:

char * const    pchc;
char * volatile pchv;

So, you can use (as per your needs)

"strcpy(serName, (char *)vptr);"  or " char*  volatile vptr = (char*) name;"

Above are the solutions for your code to run by suppressing optimization and do not pose any error either. Now you will need not implement your complete I/O yourself :)

This worked for me. Hope, it helps you as well...

Upvotes: 0

Related Questions