Click here to Skip to main content
15,887,676 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
C#
#define writel(value, address) \
    (*(volatile unsigned int *)(address)) = (value)

I wish to know whether a above define macro is typecasted or used as function pointer .

Got confused since volatile is used
Posted

It is an assignment.
The volatile keyword is (probably) used in order to force the compiler to actually perform such assignment (don't skip it by optimization).
 
Share this answer
 
Comments
steven8Gerrard 19-Oct-12 6:23am    
volatile unsigned int * // Is this meant for typecast or function pointer?? I have a basic doubt
CPallini 19-Oct-12 6:32am    
Type cast, of course.
While CPallini is of course correct, the reason for your confusion may have been the somewhat involved pointer modification in the expression (*(volatile unsigned int *)(address))

In this expression:
- unsigned int is the base type used for a (C-style) type-cast
- volatile is a type modifier (such as const), telling the compiler that the unsigned int value accessed here may change at any time
- (volatile unsigned int*) is a type-cast to 'pointer to a volatile value of type unsigned int'
- (address) is the argument to the type-cast; the brackets may be necessary, if an expression is used as an address rather than a variable or literal

A function pointer type definition looks a bit similar due to the surrounding '()', the obligatory '*', and the function argument list. I've tried to figure out how this should look like if it were to be the assignment of a function pointer, i.e. if the type cast were meant to change the type of address to a function pointer, which gets assigned a new value:

C++
(unsigned int (cdecl)())(address) = value

[edit]Checked with the compiler and fixed the type cast syntax; but the compiler doesn't accept it anyway since it won't let me assign a value to a function pointer [/edit]

Note the additional empty set of () after (address). It gives away the fact we're dealing with a function pointer rather than an ordinary one. Also, I left out volatile, because that's an invalid qualifier for return types (or, in other words, the volatile in your expression is an indication this is not a function pointer)
 
Share this answer
 
v2
Comments
CPallini 19-Oct-12 8:08am    
My 5.
Stefan_Lang 19-Oct-12 8:32am    
Thank you. I stil feel the explanation is clumsy, but that may just be my inherent dislike of macros and function pointers ;-)
steven8Gerrard 19-Oct-12 10:52am    
Thanks . Nicely explained . My 5
Hello

volatile means that operation will be performed with variable directly without using accumulator register, that mostly used in cases of multithreaded variables accessing.
For that porpose better usage of Interlocked functions.
Actually in your case: (assigment) can be used InterlockedExchange or InterlockedExchangePointer functions they are more safety then simple volatile assignment. If you not performs cross threading variables usage in that macro - then simple assignmet will be fine.

Regards,
Maxim.
 
Share this answer
 
Comments
Orjan Westin 19-Oct-12 4:44am    
The InterlockedExchange and related functions are platform-specific for Windows, though, so not much use if the target is MacOS, Linux, Solaris, or any of a number of real-time OSs.
armagedescu 19-Oct-12 11:29am    
Just keep in mind. It is about volatile, not about InterlockedExchange. Instead of InterlockedExchange you may think about any other function for cross thread data manipulation. Threading functions and objects exists in any OS which supports multithreading.
Orjan Westin 19-Oct-12 11:46am    
The use of volatile isn't restricted to multi-threading, though. It was introduced as a way to allow direct mapping to registers or memory areas tied to other hardware. In this case, it's probably there to prevent the compiler from doing unwanted optimisations, as CPallini suggests. So nothing to do with multi-threading.
armagedescu 19-Oct-12 11:59am    
Of course, it has many things to do with multithreading, and with many other things than multithreading, which can change data at any time, in an uncontrolled by compiler way. Multithreading was just by example, btw a very good example of situations when variables can change in their own way. It can be anything, just keep in mind, port data, socked data, anything which should not be touched or forced by compiller.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900