This topic created in 4026 days ago, the information mentioned may be changed or developed.
我的程序在 Ubuntu 上就能正常工作,最近在 CentOS 上运行就会出现莫名其妙的 Bug。如下:
原始代码:
static inline uint16_t
up_packet_read_uint16_be(up_packet_t *p)
{
return (*(p->pointer++) << 8) | *(p->pointer++);
}
函数只想读一个 16 Bit 大端数返回,在 Ubuntu 上, 能够正常工作, 在 CentOS 上,函数只读了第一个字节,并没有读第二个字节。谁能帮忙看下?非常感谢。
PS,up_packet_t 定义如下:
struct up_packet_s {
uint8_t *buffer;
uint8_t *pointer;
size_t length;
size_t capacity;
};
Supplement 1 · May 22, 2015
对于问题,主要的现象是 pointer 只自增了 1
Supplement 2 · May 22, 2015
谢谢大家,下次不写这么糟糕的代码了 :)
19 replies • 2015-05-23 22:58:17 +08:00
 |
|
3
choury May 22, 2015 via Android
一个语句放两个++,结果是不确定的,和编译器实现有关
|
 |
|
4
acros May 22, 2015
这不是触发短路求值了么?
我去VS里面验证下,目前没gcc····
|
 |
|
5
acros May 22, 2015
木有试出来······
三楼说的应该是对的,我记得code warrior编译器对这种的处理就和vs相反的。
|
 |
|
6
xylophone21 May 22, 2015 1
只读了第一个字节,并没有读第二个字节。这个怎么解释? 0x12 0x34 ==> 0x1200? 0x0034? 0x3412?
1. *(p->pointer++) << 8 溢出? 2. C规范定义中没有说|操作的左右顺序,但也没有说行为是未定义的。不过讲||时,它用了一个unlike,这种东西跟优先级差不多,虽然有规则,但没几个人记得住,用()规避的好。
6.5.12 Bitwise inclusive OR operator Syntax 1 inclusive-OR-expression: exclusive-OR-expression inclusive-OR-expression | exclusive-OR-expression Constraints 2 Each of the operands shall have integer type. Semantics 3 The usual arithmetic conversions are performed on the operands. 4 The result of the | operator is the bitwise inclusive OR of the operands (that is, each bit in the result is set if and only if at least one of the corresponding bits in the converted operands is set).
6.5.14 Logical OR operator Syntax 1 logical-OR-expression: logical-AND-expression logical-OR-expression || logical-AND-expression Constraints 2 Each of the operands shall have scalar type. Semantics 3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int. 4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
|
 |
|
10
leeyiw May 22, 2015 via iPhone
@ choury 行为确实感觉未定义,但是只自增了 1 感觉还是有点奇怪~
|
 |
|
14
zhicheng May 22, 2015 via Android
教科书似的“未定义行为”。
|
 |
|
15
Monad May 22, 2015
§5/4.1 Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. 另外这种东西不应该是直接(int16_t*)p->pointer然后ntohs最后p->pointer += 2么
|
 |
|
19
Monad May 23, 2015
@ xylophone21 就因为是Big Endian所以采用ntohs了, Network Byte Order 本来就是Big Endian的嘛
|