25793

Difference between extern and volatile

Question:

This question regards the difference between the volatile and extern variable and also the compiler optimization.

One extern variable defined in main file and used in one more source file, like this:

ExternTest.cpp:

short ExtGlobal; void Fun(); int _tmain(int argc, _TCHAR* argv[]) { ExtGlobal=1000; while (ExtGlobal < 2000) { Fun(); } return 0; }

Source1.cpp:

extern short ExtGlobal; void Fun() { ExtGlobal++; }

The assembly generated for this in the vs2012 as below:

ExternTest.cpp assembly for accessing the external variable

ExtGlobal=1000; 013913EE mov eax,3E8h 013913F3 mov word ptr ds:[01398130h],ax while (ExtGlobal < 2000) 013913F9 movsx eax,word ptr ds:[1398130h] 01391400 cmp eax,7D0h 01391405 jge wmain+3Eh (0139140Eh)

Source.cpp assembly for modifying the extern variable

ExtGlobal++; 0139145E mov ax,word ptr ds:[01398130h] 01391464 add ax,1 01391468 mov word ptr ds:[01398130h],ax

From the above assembly, every access to the variable "ExtGlobal" in the while loop reads the value from the corresponding address. If i add volatile to the external variable the same assembly code was generated. Volatile usage in two different threads and external variable usage in two different functions are same.

Answer1:

Asking about extern and volatile is like asking about peanuts and gorillas. They're completely unrelated.

extern is used simply to tell the compiler, "Hey, don't expect to find the definition of this symbol in this C file. Let the linker fix it up at the end."

volatile essentially tells the compiler, "Never trust the value of this variable. Even if you <em>just</em> stored a value from a register to that memory location, don't re-use the value in the register - make sure to re-read it from memory."

If you want to see that volatile causes different code to be generated, write a series of reads/writes from the variable.

For example, compiling this code in cygwin, with gcc -O1 -c,

int i; void foo() { i = 4; i += 2; i -= 1; }

generates the following assembly:

_foo proc near mov dword ptr ds:_i, 5 retn _foo endp

Note that the compiler knew what the result would be, so it just went ahead and optimized it.

Now, adding volatile to int i generates the following:

public _foo _foo proc near mov dword ptr ds:_i, 4 mov eax, dword ptr ds:_i add eax, 2 mov dword ptr ds:_i, eax mov eax, dword ptr ds:_i sub eax, 1 mov dword ptr ds:_i, eax retn _foo endp

The compiler never trusts the value of i, and <em>always</em> re-loads it from memory.

Recommend

  • set as start page in vs2012
  • PageFunction is not supported in a Windows Presentation Foundation project
  • How to use QTcreator with the Visual Studios november CTP compiler?
  • Has generic type's features/operator overloading improved in C# 5.0?
  • The type initializer for 'Emgu.CV.CvInvoke' threw an exception for Win8 64bit, VS2012
  • Moqing HttpContext
  • Getting address of data variable in x86 AT&T Assembly
  • Visual Studio 2012 doesn't build project on run when its dependencies change
  • Add date without exceeding a month
  • Invalid rgba arg “#” in matplotlib
  • Proper Mutational scale value in matplotlib
  • Message Response Zombies occurring with errors Codes 0xC0C01B4C and 0xc0c016b5 no Orchestration
  • Label Areas in Python Matplotlib stackplot
  • gridview on page won't refresh, even when calling databind again
  • matplotlib's colormap
  • How come C standard library function `strchr` returns pointer to non-const, when given `const char *
  • Sorting an array of pointers
  • Copy content of C variable into a register (GCC)
  • Monotouch floating point pointer throws NullReferenceException when not 4-byte aligned
  • GCC error: Cannot apply offsetof to member function MyClass::MyFunction
  • Use double quote then curly brace in powershell -Command
  • Create a table from a list of tuples in Python 3
  • How to prevent cross domain issues by proxying in IIS?
  • Why is my SqlPackage DeployReport returning an empty report?
  • Performance difference between accessing local and class member variables
  • ASP.NET Gridview Paging Problem
  • Access PCF DEV from external machine on same network as host
  • android.app.PendingIntent cannot be accessed ouside the package
  • Initializing a class using malloc
  • addressing in assembler
  • Netezza Incremental load from Sql server using SSIS
  • LNK1104: cannot open file 'kernel32.lib'
  • jQuery: How to AJAXify WordPress Search?
  • Mysql - How to search for 26 records that each begins with the letter of the alphabet?
  • Declaring variable dynamically in VB.net
  • How to delay loading a property with linq to sql external mapping?
  • Apache 2.4 and php-fpm does not trigger apache http basic auth for php pages
  • Join two tables and save into third-sql
  • Microsoft Visual Studio Community 2015 always crashes in Windows 10 if swithed to Visual FoxPro
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?