volatile变量作为参数的功能 [英] volatile variables as argument to function

查看:1287
本文介绍了volatile变量作为参数的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有了这个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))以得到一个功能特定的优化参数。例如, __ __属性((优化(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 a volatile 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 a volatile object is not itself volatile. Therefore, attempting to return a volatile int will result in a copy, casting it down to a non-volatile int, which is what is triggering your compiler messages. Returning a volatile int* might be useful, but not a volatile 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆