I am very new to Sparse. And During running sparse I am seeing this warning:
warning: incorrect type in argument 2 (different address spaces)
expected void volatile [noderef] <asn:2>*addr
got void *
Basically, This is happening because of following:
struct context{
void __iomem *base;
};
readl(const volatile void __iomem* add){
....
....
}
function: foo(){
struct context *var;
readl(var->base); //---> here i got the above mentioned warning
}
TO fix this I did following:
struct context{
- void __iomem *base;
+ volatile void __iomem *base;
};
And warning get removed.
My question:
- is it harmful to use "volatile" in such case. and if yes then WHY?
- What I think is that I should not make the member of struct as "volatile". But, then how we can get rid off from the Csparse warning.
As per the documentation given # https://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt
# http://lwn.net/Articles/233482/.
we should always avoid the use of volatile.
No, it's not harmful. No idea why it should or could be, harmful to what?
If the code you're calling expects a volatile pointer, then it's incorrect to pass a non-volatile one, since the code in the calling context might not be properly adapted to the requirements of a volatile value in that case.
volatile instructs the compiler not to do any optimization for that variable. Thus, it would provide guarantee that the latest value of variable to use. This may be altered by an external event.
volatile is generally used when dealing with external events, like interrupts of hardware related pins.
I don't think, it's harmful. But why should one use when not needed, because optimization helps in better efficiency, so if you are sure that even if the variable is optimized, it cannot be altered by external event, then fine, no volatile then.
Related
Refer to the following code:
void calledFunction(volatile uint8_t **inPtr);
volatile uint8_t buffer[] = {0,0,0,0,0,0};
volatile uint8_t *headPtr = buffer;
void foo(void)
{
volatile uint8_t *tmpPtr = NULL;
tmpPtr = headPtr;
//This function modifies tmpPtr
calledFunction(&tmpPtr);
headPtr = tmpPtr;
return;
}
This is a simplified version of code that I am attempting to make interrupt-safe, and I am not sure why this local is defined as a volatile. I know that there is no performance reason (i.e. to guarantee at least O(n) for this function) because this function should run as efficiently as possible.
This function can be called in both main execution and inside interrupts, but since tmpPtr is a nonstatic local variable, it should not be able to be modified by any other instance of foo().
I can't see any access pattern that would require the volatile keyword in this context.
In short, What is the purpose of the volatile keyword for tmpPtr in function foo()?
EDIT:Forgot a & in function argument
EDIT2: I have inherited this code and need to modify it.
My main question is whether the volatile keyword has any special effective reason for being in this context.
EDIT3: Added the prototype for calledFunction()
EDIT4: Added important clarification in original code that headPtr and buffer both have volatile
The reason tmpPtr has volatile is due to tmpPtr needing to reference a volatile uint8_t, not because tmpPtr itself is volatile (it isn't).
As initially pointed out by #Eugene Sh., this question came up due to a misunderstanding in syntax when defining volatile pointers and variables. This question has a great explanation of syntax for pointers to volatile vs volatile pointers.
Volatile restricts the compiler from optimizations when accessing (reading or writing) the data this pointer points to.
This comes up in embedded or interrupts often because memory-mapped peripherals can't have what would normally be "extraneous" reads or writes optimized out.
E.g.,
int32_t variable = 0;
variable = 1;
variable = 2;
variable = 3;
An optimizing compiler would skip setting the value of variable to 0, 1, and 2 and just set it to 3. That's fine generally, but if instead of writing to a normal variable we are writing to a memory-mapped port, we actually want each of those writes to happen.
This can happen even outside the world of hardware interfaces. If a separate thread is in a loop looking for variable to be set to 2, an optimizing compiler would preclude this from happening.
The fact that it's local is not material. It's just that most use cases for volatile happen be implemented with translation-unit (or cross-translation-unit using extern) scope.
Two examples are memory-mapped register definitions (the struct is typically global, often in a header file, and commonly the instance of the pointer to the struct is global though it doesn't have to be), and flags like our thread example.
I don't advocate for either design, but you will come across it frequently in embedded development.
I thought I knew C pretty well, but I'm confused by the following code:
typedef struct {
int type;
} cmd_t;
typedef struct {
int size;
char data[];
} pkt_t;
int func(pkt_t *b)
{
int *typep;
char *ptr;
/* #1: Generates warning */
typep = &((cmd_t*)(&(b->data[0])))->type;
/* #2: Doesn't generate warning */
ptr = &b->data[0];
typep = &((cmd_t*)ptr)->type;
return *typep;
}
When I compile with GCC, I get the "dereferencing type-punned pointer will break strict-aliasing rules" warning.
Why am I getting this warning at all? I'm dereferencing at char array. Casting a char * to anything is legal. Is this one of those cases where an array is not exactly the same as a pointer?
Why aren't both assignments generating the warning? The 2nd assignment is the equivalent of the first, isn't it?
When strict aliasing is turned on, the compiler is allowed to assume that two pointers of different type (char* vs cmt_t* in this instance) will not point to the same memory location. This allows for a greater range of optimizations which you would otherwise not want to be applied if they do indeed point to the same memory location. Various examples/horror-stories can be found in this question.
This is why, under strict-aliasing, you have to be careful how you do type punning. I believe that the standard doesn't allow for any type-puning what-so-ever (don't quote me on that) but most compilers have exemption for unions (my google-fu is failing in turning up the relevant manual pages):
union float_to_int {
double d;
uint64_t i;
};
union float_to_int ftoi;
ftoi.d = 1.0;
... = ftoi.i;
Unfortunately, this doesn't quite work for your situation as you would have to memcpy the content of the array into the union which is less then ideal. A simpler approach would be to simply to turn off strict-aliasing via the -fno-strict-aliasing switch. This will ensure that your code is correct and it's unlikely to have a significant performance impact (do measure if performance matters).
As for why the warning doesn't show up when the line is broken up, I don't know. Chances are that the modifications to the source code manages to confuse the compiler's static analysis pass enough that it doesn't see the type-punning. Note that the static analysis pass responsible for detecting type-punning is unrelated and doesn't talk to the various optimization passes that assume strict-aliasing. You can think of any static analysis done by compilers (unless otherwise specified) as a best-effort type of thing. In other words, the absence of warning doesn't mean that there are no errors which means that simply breaking up the line doesn't magically make your type-punning safe.
When designing a C interface, it is common to let into the public interface (.h) only what needs to be known by the user program.
Hence for example, the inner components of structures should remain hidden if the user program does not need to know them. This is indeed good practice, as the content and behavior of the struct could change in the future, without affecting the interface.
A great way to achieve that objective is to use incomplete types.
typedef struct foo opaqueType;
Now an interface using only pointers to opaqueType can be built, without the user program ever needing to know the inner working of struct foo.
But sometimes, it can be required to allocate such structure statically, typically on stack, for performance and memory fragmentation issues. Obviously, with above construction, opaqueType is incomplete, so its size is unknown, so it cannot be statically allocated.
A work around is to allocate a "shell type", such as :
typedef struct { int faketable[8]; } opaqueType;
Above construction enforces a size and an alignment, but doesn't go farther into describing what the structure really contains. So it matches the objective of keeping the type "opaque".
It mostly works. But in one circumstance (GCC 4.4), the compiler complains that it breaks strict-aliasing, and it generates buggy binary.
Now, I've read a ton of things about strict aliasing, so I guess I understand now what it means.
The question is : is there a way to define an opaque type which can nonetheless be allocated on stack, and without breaking strict aliasing rule ?
Note that I've attempted the union method described in this excellent article but it still generates the same warning.
Note also that visual, clang and gcc 4.6 and later don't complain and work fine with this construction.
[Edit] Information complement :
According to tests, the problem only happens in the following circumstances :
Private and public type different. I'm casting the public type to private inside the .c file. It doesn't matter apparently if they are part of the same union. It doesn't matter if the public type contains char.
If all operations on private type are just reads, there's no problem. Only writes cause problems.
I also suspect that only functions which are automatically inlined get into trouble.
Problem only happens on gcc 4.4 at -O3 setting. -O2 is fine.
Finally, my target is C90. Maybe C99 if there really is no choice.
You can force the alignment with max_align_t and you can avoid the strict aliasing issues using an array of char since char is explicitly allowed to alias any other type.
Something along the lines of:
#include <stdint.h>
struct opaque
{
union
{
max_align_t a;
char b[32]; // or whatever size you need.
} u;
};
If you want to support compiler that do not have the max_align_t, or if you know the alignment requirements of the real type, then you can use any other type for the a union member.
UPDATE: If you are targetting C11, then you may also use alignas():
#include <stdint.h>
#include <stdalign.h>
struct opaque
{
alignas(max_align_t) char b[32];
};
Of course, you can replace the max_align_t with whatever type you think appropriate. Or even an integer.
UPDATE #2:
Then, the use of this type in the library would be something along the lines of:
void public_function(struct opaque *po)
{
struct private *pp = (struct private *)po->b;
//use pp->...
}
This way, since you are type-punning a pointer to char you are not breaking the strict aliasing rules.
What you desire is some kind of equivalent of the C++ private access control in C. As you know, no such equivalent exists. The approach you give is approximately what I would do. However, I would make the opaqueType opaque to the inner components implementing the type, so I would be forced to cast it to the real type within the inner components. The forced cast should not generate the warning you are mentioning.
Although cumbersome to use, you can define an interface that provides "stack allocated" memory to an opaque type without exposing a sized structure. The idea is that the implementation code is in charge of the stack allocation, and the user passes in a callback function to get a pointer to the allocated type.
typedef struct opaqueType_raii_callback opqaueType_raii_callback;
struct opaqueType_raii_callback {
void (*func)(opqaueType_raii_callback *, opqaueType *);
};
extern void opaqueType_raii (opaqueType_raii_callback *);
extern void opaqueType_raii_v (opaqueType_raii_callback *, size_t);
void opaqueType_raii (opaqueType_raii_callback *cb) {
opaqueType_raii_v(cb, 1);
}
void opqaueType_raii_v (opaqueType_raii_callback *cb, size_t n) {
opaqueType x[n];
cb->func(cb, x);
}
The definitions above look a bit esoteric, but it is the way I normally implement a callback interface.
struct foo_callback_data {
opaqueType_raii_callback cb;
int my_data;
/* other data ... */
};
void foo_callback_function (opaqueType_raii_callback *cb, opaqueType *x) {
struct foo_callback_data *data = (void *)cb;
/* use x ... */
}
void foo () {
struct foo_callback_data data;
data.cb.func = foo_callback_function;
opaqueType_raii(&data.cb);
}
For me this seems to be something which just shouldn't be done.
The point of having an opaque pointer is to hide the implementation details. The type and alignment of memory where the actual structure is allocated, or whether the library manages additional data beyond what's pointed to are also implementation details.
Of course not that you couldn't document that one or another thing was possible, but the C language uses this approach (strict aliasing), which you can only more or less hack around by Rodrigo's answer (using max_align_t). By the rule you can't know by the interface what kind of constraints the particular compiler would impose on the actual structure within the implementation (for some esoteric microcontrollers, even the type of memory may matter), so I don't think this can be done reliably in a truly cross platform manner.
First, we have InterlockedExchange64();
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683593%28v=vs.85%29.aspx
LONGLONG __cdecl InterlockedExchange64( __inout LONGLONG volatile *Target, __in LONGLONG Value );
Second, we have the compiler intrinsic, _InterlockedExchange64(), note the absence of volatile;
http://msdn.microsoft.com/en-us/library/1s26w950%28v=vs.80%29.aspx
__int64 _InterlockedExchange64( __int64 * Target, __int64 Value );
Next, we have InterlockedExchangePointer() which like InterlockedExchange64(), uses volatile.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683609%28v=vs.85%29.aspx
PVOID __cdecl InterlockedExchangePointer( __inout PVOID volatile *Target, __in PVOID Value );
But now we come to the intrinsic for pointer exchange, _InterlockedExchangePointer() and here we see volatile used!
http://msdn.microsoft.com/en-us/library/853x471w.aspx
void * _InterlockedExchangePointer( void * volatile * Target, void * Value );
The underlying instruction is the same in all cases, so what gives? documentation error?
The GCC instrincs don't mention volatile for exchange, but then they don't mention it for CAS either! so that doesn't help.
My view is that a CAS target is volatile, because you can only know at run time if the exchange will occur; but atomic exchange should not be volatile, because the target is always updated (even if it's value doesn't change), so the compiler has no uncertainty.
I see also the function for InterlockedIncrement() are volatile, but the instrincs are not. The intrinsics for CAS have volatile for their destinations.
MSDN is riddled with mostly minor documentation errors (for instance, __readfsdword was marked as kernel only under the VS 2005 docs), what you should really pay attention to is the definition the compiler uses, in this case, the definitions in intrin.h (taken from VS2010 Ultimate SP1):
__MACHINEI(long _InterlockedExchange(long volatile *, long))
__MACHINEIA64(__int64 _InterlockedExchange64(__int64 volatile *, __int64))
as we can see they are indeed volatile pointers that are required.
One final thing to note, all your links are the VS 2005 docs (default linked to by google for older intrinsics), so make sure you use the drop down at the top of the page to switch to the latest versions.
It's not that pointer to volatile is required by these function it is that it is allowed. That is, if the parameters were declared as long* instead of long volatile* then passing the address of a volatile variable would give this error:
cannot convert argument 1 from 'volatile LONGLONG *' to 'LONGLONG *'
This can be seen with this simple code:
LONGLONG a;
volatile LONGLONG b;
void DoSomething(LONGLONG* p) {}
int main() {
DoSomething(&a);
DoSomething(&c); // Error!
return 0;
}
There is a long tradition in C/C++ of misusing volatile as a way to indicate that a variable may be modified by other threads. This is misguided because volatile doesn't not actually give meaningfully useful semantics for multi-threading, but when C++ didn't acknowledge multi-threading developers got desperate. The problem with using volatile is that it does not prevent compiler or CPU reordering so it it is wrong, say, 99% of the time in multi-threaded code.
Absent C++11 the safe thing to do is to only ever reference these thread-shared variables using Interlocked* functions. If you do this then volatile is unnecessary. Or, use locks like a sane person.
But, since lots of developers tag their thread-shared variables with atomic it is necessary for Interlocked* functions to accept those variables. And that is why they all take the type of pointer-to-volatile.
How do you declare a particular member of a struct as volatile?
Exactly the same as non-struct fields:
#include <stdio.h>
int main (int c, char *v[]) {
struct _a {
int a1;
volatile int a2;
int a3;
} a;
a.a1 = 1;
a.a2 = 2;
a.a3 = 3;
return 0;
}
You can mark the entire struct as volatile by using "volatile struct _a {...}" but the method above is for individual fields.
Should be pretty straight forward according to this article:
Finally, if you apply volatile to a
struct or union, the entire contents
of the struct/union are volatile. If
you don't want this behavior, you can
apply the volatile qualifier to the
individual members of the
struct/union.
I need to clarify volatile for C/C++ because there was a wrong answer here. I've been programming microcontroleurs since 1994 where this keyword is very useful and needed often.
volatile will never break your code, it is never risky to use it. The keyword will basically make sure the variable is not optimized by the compiler. The worst that shold happen if you overuse this keyword is that your program will be a bit bigger and slower.
Here is when you NEED this keyword for a variable :
- You have a variable that is written to inside an interrupt function.
AND
- This same variable is read or written to outside interrupt functions.
OR
If you have 2 interrupt functions of different priority that use the variable, then you should also use 'volatile'.
Otherwise, the keyword is not needed.
As for hardware registers, they should be treated as volatile even without the keyword if you don't do weird stuff in your program.
I just finished a data structure in which it was obvious where the volatile qualifier was required, but for a different reason than the ones stated above: It is simply because the struct requires a forceful locking mechanism because of (i) direct access and (ii) equivalent invocation.
Direct access deals with sustained RAM reading and writing.
Equivalent invocation deals with interchangeable method flows.
I haven't had much luck with this keyword unless the compiler knows exactly what to do about it. And that's my own personal experience. But I am interested in studying how it directly impacts a cross-platform compilation such as between a low-level system call and a back-end database.