由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 问一个volatile和memcpy一起用的问题
相关主题
被苹果给惊呆了!! (转载)*(&b1)=b编译不过,b1=b可以,区别是?
专业c++程序员都用什么ide (转载)C++ pointer to function is buggy
牛人们来看看这个Dao语言怎么样C语言重复定义问题
C++11 support is now feature-complete in clang.请推荐一款windows xp 平台上优秀的C语言编译/编辑器
C++ 11问题:emplace_back()大家要学习C++11啊, 我觉得C++11很多FEATURE,绝对不输JAVA.
感觉python的前途堪忧 (转载)我老不厚道地说一句,C的工作稳定是假的。
c++什么编译器好使?批判Rust语言,以及C/C++为什么永远不会死(ZZ)
C puzzle 一日一题[合集] 6个变态的C语言写的Hello World (ZZ)
相关话题的讨论汇总
话题: memcpy话题: volatile话题: void话题: a2话题: a1
进入Programming版参与讨论
1 (共1页)
r****o
发帖数: 1950
1
typedef struct
{
...
}s_t;
s_t a1;
volatile s_t a2;
...
//assume a1 is initiliazed with some value, and we want to copy its value to
a2
memcpy(&a2, &a1, sizeof(s_t));
这里能直接这么用memcpy吗?会有什么问题呢?
正确的写法应该怎么写?
t****t
发帖数: 6806
2
i supppose not, since memcpy only take void* or const void*. volatile void*
doesn't convert to void* implicitly. so you have to do an explicit cast.

to

【在 r****o 的大作中提到】
: typedef struct
: {
: ...
: }s_t;
: s_t a1;
: volatile s_t a2;
: ...
: //assume a1 is initiliazed with some value, and we want to copy its value to
: a2
: memcpy(&a2, &a1, sizeof(s_t));

F********g
发帖数: 475
3
depend on the compiler
s*****n
发帖数: 5488
4
面试题吗?volatile const指针不可以用于memcpy.
如果是外设的寄存器,memcpy过去你就惨了。考虑到外设非常可能在并发的工作。
一个字节一个字节的copY?

to

【在 r****o 的大作中提到】
: typedef struct
: {
: ...
: }s_t;
: s_t a1;
: volatile s_t a2;
: ...
: //assume a1 is initiliazed with some value, and we want to copy its value to
: a2
: memcpy(&a2, &a1, sizeof(s_t));

r****o
发帖数: 1950
5
谢谢,你是说在memcpy里面的参数里面加cast?
memcpy((volatile *)&a2, &a1, sizeof(s_t));
还有你看这样行不行?
typedef volatile struct
{
...
}s_t;
s_t a1;
s_t a2;
memcpy(&a2, &a1, sizeof(s_t));
这样a1,a2都是volatile,是不是就可以用memcpy了?
a1本来不必是volatile,但是加上volatile是不是也没有大问题?只是多了一点
overhead而已?

*
////////////
typedef struct
{
...
}s_t;
s_t a1;
volatile s_t a2;
...
//assume a1 is initiliazed with some value, and we want to copy its value to
a2
memcpy(&a2, &a1, sizeof(s_t));
这里能直接这么用memcpy吗?会有什么问题呢?
正确的写法应该怎么写?

【在 t****t 的大作中提到】
: i supppose not, since memcpy only take void* or const void*. volatile void*
: doesn't convert to void* implicitly. so you have to do an explicit cast.
:
: to

S**I
发帖数: 15689
6
你没明白thrust的意思。memcpy的prototype是
void * memcpy ( void * destination, const void * source, size_t num )
&a2的类型要被cast成void *,&a1的类型要被cast成const void *,a2(和a1)的类型
是volatile,所以cast可能需要是explicit的。
你应该写成
memcpy((void *)&a2, (const void *)&a1, sizeof(s_t))

void
to

【在 r****o 的大作中提到】
: 谢谢,你是说在memcpy里面的参数里面加cast?
: memcpy((volatile *)&a2, &a1, sizeof(s_t));
: 还有你看这样行不行?
: typedef volatile struct
: {
: ...
: }s_t;
: s_t a1;
: s_t a2;
: memcpy(&a2, &a1, sizeof(s_t));

r****o
发帖数: 1950
7
多谢,
是不是如果a1,a2都不是volatile,memcpy会implicit的进行(void *)和(const void *
)的cast。
但是如果a2是volatile,那么就必须进行(const void *)的cast。
进行了这个cast之后,是不是就能把一个non-valatile的结构copy给valatile的结构了?

【在 S**I 的大作中提到】
: 你没明白thrust的意思。memcpy的prototype是
: void * memcpy ( void * destination, const void * source, size_t num )
: &a2的类型要被cast成void *,&a1的类型要被cast成const void *,a2(和a1)的类型
: 是volatile,所以cast可能需要是explicit的。
: 你应该写成
: memcpy((void *)&a2, (const void *)&a1, sizeof(s_t))
:
: void
: to

S**I
发帖数: 15689
8

*
了?


【在 r****o 的大作中提到】
: 多谢,
: 是不是如果a1,a2都不是volatile,memcpy会implicit的进行(void *)和(const void *
: )的cast。
: 但是如果a2是volatile,那么就必须进行(const void *)的cast。
: 进行了这个cast之后,是不是就能把一个non-valatile的结构copy给valatile的结构了?

r****o
发帖数: 1950
9
谢谢,不过我还是没弄明白为什么有volatile就必须进行explicit cast。能再说说吗?
r****o
发帖数: 1950
10
谢谢,不过我还是没弄明白为什么有volatile就必须进行explicit cast。能再说说吗?
相关主题
感觉python的前途堪忧 (转载)*(&b1)=b编译不过,b1=b可以,区别是?
c++什么编译器好使?C++ pointer to function is buggy
C puzzle 一日一题C语言重复定义问题
进入Programming版参与讨论
S**I
发帖数: 15689
11
C++标准里没说volatile的指针可以implicitly cast,是否必须explicitly cast就要
看具体的实现了。有的编译器允许implicitly cast,但是会给warning,有的就不允许。

吗?

【在 r****o 的大作中提到】
: 谢谢,不过我还是没弄明白为什么有volatile就必须进行explicit cast。能再说说吗?
t****t
发帖数: 6806
12
规定就是这样的, you can add more qualifier implicitly, not the other way.

吗?

【在 r****o 的大作中提到】
: 谢谢,不过我还是没弄明白为什么有volatile就必须进行explicit cast。能再说说吗?
r****o
发帖数: 1950
13
多谢,除了volatile还有什么其他类型的指针需要exlicitly cast吗?

许。

【在 S**I 的大作中提到】
: C++标准里没说volatile的指针可以implicitly cast,是否必须explicitly cast就要
: 看具体的实现了。有的编译器允许implicitly cast,但是会给warning,有的就不允许。
:
: 吗?

t****t
发帖数: 6806
14
事实上, 允许implicit cast的都列出来了, 没列出来的都是非法的.

许。

【在 S**I 的大作中提到】
: C++标准里没说volatile的指针可以implicitly cast,是否必须explicitly cast就要
: 看具体的实现了。有的编译器允许implicitly cast,但是会给warning,有的就不允许。
:
: 吗?

r****o
发帖数: 1950
15
谢谢,C标准也是这样的吗?

许。

【在 S**I 的大作中提到】
: C++标准里没说volatile的指针可以implicitly cast,是否必须explicitly cast就要
: 看具体的实现了。有的编译器允许implicitly cast,但是会给warning,有的就不允许。
:
: 吗?

k****e
发帖数: 126
16
C99里面对function call是这样规定的,6.5.2.2 Function calls:
If the expression that denotes the called function has a type that does
include a prototype, the arguments are implicitly converted, as if by
assignment, to the types of the corresponding parameters, taking the type of
each parameter to be the unqualified version of its declared type.
对于assignment是这样规定的,6.5.16.1 Simple assignment:
one operand is a pointer to an object or incomplete type and the other is a
pointer to a qualified or unqualified version of void, and the type pointed
to by the left has all the qualifiers of the type pointed to by the right;
最后一句话说的就是lz这种情况了,所以在赋值语句左边的指针所指向的数据类型必须
包含赋值语句右边指针所指向的数据类型的所有qualifiers,只有符合这种前提的时候
才可以做隐性类型转换。
memcpy的原型是void * memcpy ( void * destination, const void * source, size_
t num )
你的这句话“memcpy(&a2, &a1, sizeof(s_t));”中,&a2的类型是(volatile s_t *
),不可以直接赋值给类型为(void *)的指针,因此这种simple assignment不适用于
你的这个function call,需要做显性类型转换。

【在 r****o 的大作中提到】
: 谢谢,C标准也是这样的吗?
:
: 许。

r****o
发帖数: 1950
17
非常感谢!
也感谢thrust和SETI的回答。

of
a
pointed

【在 k****e 的大作中提到】
: C99里面对function call是这样规定的,6.5.2.2 Function calls:
: If the expression that denotes the called function has a type that does
: include a prototype, the arguments are implicitly converted, as if by
: assignment, to the types of the corresponding parameters, taking the type of
: each parameter to be the unqualified version of its declared type.
: 对于assignment是这样规定的,6.5.16.1 Simple assignment:
: one operand is a pointer to an object or incomplete type and the other is a
: pointer to a qualified or unqualified version of void, and the type pointed
: to by the left has all the qualifiers of the type pointed to by the right;
: 最后一句话说的就是lz这种情况了,所以在赋值语句左边的指针所指向的数据类型必须

S**I
发帖数: 15689
18
我拿几个编译器试了一下,默认的编译设置下,所有的编译器都是给warning,但是允
许通过:
GCC 4.8
LLVM-GCC 4.2.1
Clang
ICC
Visual C++
GCC 4.8, LLVM-GCC 4.2.1和Clang的warning message里明确说明编译的时候volatile
给去掉了,ICC和VC没说,不过我估计实现也差不多。

【在 t****t 的大作中提到】
: 事实上, 允许implicit cast的都列出来了, 没列出来的都是非法的.
:
: 许。

d***a
发帖数: 13752
19
C语言中volatile的意思,是指除当前程序之外,此变量有可能被系统其它部分(例如
中断或信号handler或I/O硬件)改变。
如果这个结构真的是volatile,那么有可能在memcpy运行到一半时,内存的内容改变了
(比如说发生了中断,修改了结构内容)。拷出去的结构内容,一部分是旧的,一部分
是新的,这样最后的内容就错了。加casting可以防止编译器报错,但运行时还是会出
问题。
如果volatile是你自己加的,其实这个结构并不volatile,那就不用担心了。

to

【在 r****o 的大作中提到】
: typedef struct
: {
: ...
: }s_t;
: s_t a1;
: volatile s_t a2;
: ...
: //assume a1 is initiliazed with some value, and we want to copy its value to
: a2
: memcpy(&a2, &a1, sizeof(s_t));

r****o
发帖数: 1950
20
谢谢。我在memcpy前后有中断关闭和恢复,应该可以防止这种错误。

【在 d***a 的大作中提到】
: C语言中volatile的意思,是指除当前程序之外,此变量有可能被系统其它部分(例如
: 中断或信号handler或I/O硬件)改变。
: 如果这个结构真的是volatile,那么有可能在memcpy运行到一半时,内存的内容改变了
: (比如说发生了中断,修改了结构内容)。拷出去的结构内容,一部分是旧的,一部分
: 是新的,这样最后的内容就错了。加casting可以防止编译器报错,但运行时还是会出
: 问题。
: 如果volatile是你自己加的,其实这个结构并不volatile,那就不用担心了。
:
: to

d***a
发帖数: 13752
21
对,单核单进程程序,就是这个解决方法。多核多进程程序,就得用同步了。

【在 r****o 的大作中提到】
: 谢谢。我在memcpy前后有中断关闭和恢复,应该可以防止这种错误。
1 (共1页)
进入Programming版参与讨论
相关主题
[合集] 6个变态的C语言写的Hello World (ZZ)C++ 11问题:emplace_back()
求GCC高手感觉python的前途堪忧 (转载)
haskell 好像还不支持arm 64吧。c++什么编译器好使?
Mavericks 9.2 and clang 5.1C puzzle 一日一题
被苹果给惊呆了!! (转载)*(&b1)=b编译不过,b1=b可以,区别是?
专业c++程序员都用什么ide (转载)C++ pointer to function is buggy
牛人们来看看这个Dao语言怎么样C语言重复定义问题
C++11 support is now feature-complete in clang.请推荐一款windows xp 平台上优秀的C语言编译/编辑器
相关话题的讨论汇总
话题: memcpy话题: volatile话题: void话题: a2话题: a1