The function is unstable. How to fix?

I use a variable between two threads. And I use volatile to avoid optimization.

However, it shows an error for instability in strcpy. (as shown below)

How can I fix this error correctly?

Some guy told me that I was dropping volatility. But if I discarded the volatility, then I lost the goal of volatility .... and may ultimately get a run-time error from optimization ..... right?

Thank you very much.

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

On the other hand, I can write my own strcpy to support volatile. But this is strange. because if so, should I write my own I / O stream (or these complex functions) every time I use volatile?

thanks a again for the answer.

+4
source share
2 answers

You do not seem to have a clear understanding of what “variability” means. The value is more or less "Hello, compiler, please note that someone else will change this variable, so you cannot assume that if your code does not write, the value will remain constant. In addition, someone can watch this a variable, so when I write this variable, please don’t do the weird thing on the assumption that it doesn’t matter, because for those other guys who watch it it’s important, just write what I want you to write, and when I tell you to do it. "

When is it important to use "volatile?" Here is an example:

 volatile int stopflag; // flag will be set by an interrupt handler void mainloop() { stopflag = 0; while (!stopflag) { ... } } 

If the code at three points never touches the stopflag and never calls a function with an unknown implementation, then the compiler may be tempted to avoid reading the flag in a loop, because looking at the code itself, it seems 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 may be tempted to just write 0xFF in place instead of writing all the intermediate values.

Please note that using volatile to synchronize threads on modern hardware is not enough. On modern computers, the processor is usually multi-core, and therefore writing and reading is no longer an atomic operation. Although in the past (on single-core processors) in practice it was often possible to use mutable variables to synchronize threads, now this is a lie.

It seems to you really interesting to say that buffer is indeed read and written by others, but in this case the buffer address is publicly available, therefore, whenever a function is called (unless it is built-in or has a known implementation code), the compiler should assume that the contents of the buffer are possible changed or will be read by an unknown code.

I would promise that the thread synchronization primitives are properly declared to make sure this is also true in your case (even if strcpy is inline).

+4
source

I can understand that in some places (when using threads) we don’t want optimization to happen, and for this we use the “volatile” keyword.

Contact MSDN for

To declare an object that the pointer points to as const or volatile, use the form declaration:

 const char *cpch; volatile char *vpch; 

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

 char * const pchc; char * volatile pchv; 

So you can use (according to your needs)

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

The above solutions for your code are triggered by suppressing optimizations and present no error. Now you will not need to do your full I / O yourself :)

It worked for me. Hope this helps you ...

0
source

All Articles