volatile变量作为参数的功能 [英] volatile variables as argument to function
问题描述
有了这个code:
的typedef挥发性诠释计数;COUNT functionOne(COUNT *号);INT functionTwo为(int *号);
我无法摆脱一些警告。
我在functionOne原型得到这样的警告1
【警告】键入预选赛上被忽略
函数返回类型
块引用>和我得到这样的警告2,无论我叫functionTwo具有计数指针参数,而不是一个int指针
【警告】投丢弃预选赛
指针目标类型
块引用>显然变量/指针不能被投挥发性/非挥发性..但每一个参数必须指定为易失呢?所以我怎么可以使用任何库函数,如果它是非易失性的变量已经定义?
修改:使用gcc -std = C99 -pedantic -Wall -Wshadow -Wpointer-ARITH -Wcast-QUAL -Wextra -Wstrict的原型-Wmissing的原型
修改:在尤卡Suomela建议这是一个警告code样品两个
的typedef挥发性诠释计数;静态INT functionTwo为(int *号){
返回*号+ 1;
}诠释主要(无效){
COUNT计数= 10;
数= functionTwo(放大器;计数);
返回0;
}
解决方案的
挥发性
关键字被设计被应用到重新present存储,而不是对象功能。返回一个挥发性INT
从函数没有太大的意义。一个函数的返回值将不会被优化掉(用内联函数可能是个例外,但是这完全是另一种情况......),并没有外部的演员将被修改。当函数返回时,它把返回值的副本到调用函数。一个的副本挥发性
对象本身不是挥发性
。因此,试图返回一个挥发性INT
将导致一个副本,铸造下来到非易失性INT
,这是什么触发你的编译器的消息。返回一个挥发为int *
可能是有用的,但不是挥发性INT
。按值传递对象插入功能使对象的副本,从而使用
挥发性INT
作为函数参数必然涉及忽略限定符转换。按地址传递一个动荡是完全合理的,但不是值。根据C规范,行为
挥发性
完全是依赖于实现的,所以因人而异。您使用
挥发性
以这种方式来试图打败一些编译器优化的?如果是这样,有可能是一个更好的方式来做到这一点。编辑:
考虑到更新你的问题,看来,你可以以不同的方式接近这一点。如果你试图打败编译器优化,为什么不采取直接的方法,只是告诉编译器不优化一些事情?您可以使用<一个href=\"http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html#Function-Specific-Option-Pragmas\"><$c$c>#pragma GCC优化 或<一个href=\"http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040$c$c_007bnothrow_007d-function-attribute-2418\"><$c$c>__attribute__((optimize))$c$c>以得到一个功能特定的优化参数。例如,__ __属性((优化(0)))
应该禁用所有的优化对于一个给定的功能。这样,你可以保持您的数据类型的非易失性,避免您遇到的问题类型。如果禁用所有的优化是有点太多了,你也可以打开或关闭该属性/编译各个优化选项。编辑:
我能够编译下面code没有任何警告或错误:静态INT functionTwo为(int *号){
返回*号+ 1;
}工会的typedef {
INT I;
挥发性INT伏;
} fancy_int;诠释主要(无效){
fancy_int计数;
count.v = 10;
count.v = functionTwo(安培; count.i);
返回0;
}本<击>破解罢>技术可能有某种奇怪的副作用,所以在生产中使用测试它彻底。这是最有可能的没有什么不同直接铸造的地址到
(INT *)
,但不会触发任何警告。Having this code:
typedef volatile int COUNT; COUNT functionOne( COUNT *number ); int functionTwo( int *number );
I can't get rid of some warnings..
I get this warning 1 at functionOne prototype
[Warning] type qualifiers ignored on function return type
and I get this warning 2, wherever I call functionTwo with a COUNT pointer argument instead of an int pointer
[Warning] cast discards qualifiers from pointer target type
obviously variables/pointers can't be "cast" to volatile/un-volatile.. but every arguments must be specified as volatile too? so how can I use any library function if it's already defined for non-volatile variable?
EDIT: Using gcc -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wextra -Wstrict-prototypes -Wmissing-prototypes
EDIT: After Jukka Suomela advice this is a code sample for warning two
typedef volatile int COUNT; static int functionTwo(int *number) { return *number + 1; } int main(void) { COUNT count= 10; count = functionTwo(&count); return 0; }
解决方案The
volatile
keyword was designed to be applied to objects that represent storage and not to functions. Returning avolatile int
from a function does not make much sense. The return value of a function will not be optimized away (with the possible exception of inlined functions, but that's another case altogether...), and no external actor will be modifying it. When a function returns, it passes a copy of the return value to the calling function. A copy of avolatile
object is not itselfvolatile
. Therefore, attempting to return avolatile int
will result in a copy, casting it down to a non-volatileint
, which is what is triggering your compiler messages. Returning avolatile int*
might be useful, but not avolatile int
.Passing an object by value into a function makes a copy of the object, thus using a
volatile int
as a function parameter necessarily involves a conversion that ignores a qualifier. Passing a volatile by address is perfectly reasonable, but not by value.According to the C spec, the behavior of
volatile
is completely implementation-dependent, so YMMV.Are you using
volatile
in this way to try to defeat some sort of compiler optimization? If so, there is probably a better way to do it.Edit: Taking into account the updates to your question, it appears that you may be able to approach this in a different way. If you are trying to defeat compiler optimizations, why not take the direct approach and simply tell the compiler not to optimize some things? You can use
#pragma GCC optimize
or__attribute__((optimize))
to give specific optimization parameters for a function. For example,__attribute__((optimize(0)))
should disable all optimizations for a given function. That way, you can keep your data types non-volatile and avoid the type problems you are having. If disabling all optimizations is a bit too much, you can also turn individual optimization options on or off with that attribute/pragma.Edit: I was able to compile the following code without any warnings or errors:
static int functionTwo(int *number) { return *number + 1; } typedef union { int i; volatile int v; } fancy_int; int main(void) { fancy_int count; count.v = 10; count.v = functionTwo(&count.i); return 0; }
This
hack"technique" probably has some kind of odd side-effects, so test it thoroughly before production use. It's most likely no different that directly casting the address to a(int*)
, but it doesn't trigger any warnings.这篇关于volatile变量作为参数的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!