为什么 "Impossible constraint" 使用类型化的 8 位常量而不是等效的 #define?
Why "Impossible constraint" with a typed 8-bit constant but not with an equivalent #define?
我在 AVR 8 位微控制器(如 ATtiny1634 或 ATmega328)的内联汇编代码中使用约束 "M"
标记的 8 位类型常量收到有关使用不可能约束的错误消息:
static const uint8_t tail_mask = (uint8_t)((rx1::queue_length-1) << \
rx1::queue_length_bits) & 0xFF;
asm(
...
"andi r30, %0\n\t"
...
:
: "M" (tail_mask)
);
warning: asm operand 1 probably doesn't match constraints
这里rx1
是一个class名字,queue_length
和queue_length_bits
都是static const uint8_t
class常量。我可以用"O"
,"N"
,没办法。使用 static
、int8_t
与否没有区别。
如果我用 #define
替换上面的 static const uint8_t
定义,错误消息就会消失!
#define tail_mask ((rx1::queue_length-1) << rx1::queue_length_bits)
asm(
...
"andi r30, %0\n\t"
...
:
: "M" (tail_mask)
);
编译正常!
这让我很烦恼。为什么使用强制的 8 位无符号常量会在强制其成为... 8 位无符号常量的约束上产生错误消息?
郑重声明,我使用的是 avr-gcc
版本 7.1.0.
传递给约束的值在这里应该是一个32位整数。当你使用 #define 时你会得到什么,因为它被静默地提升为预期的类型。同样,使用 int 或 unsigned 作为 tail_mask 值也可以。奇怪的是我经历了 documentation 的几个版本,但没有发现 M 约束参数不能是 uint8_t 或类似的证据。
我在 AVR 8 位微控制器(如 ATtiny1634 或 ATmega328)的内联汇编代码中使用约束 "M"
标记的 8 位类型常量收到有关使用不可能约束的错误消息:
static const uint8_t tail_mask = (uint8_t)((rx1::queue_length-1) << \
rx1::queue_length_bits) & 0xFF;
asm(
...
"andi r30, %0\n\t"
...
:
: "M" (tail_mask)
);
warning: asm operand 1 probably doesn't match constraints
这里rx1
是一个class名字,queue_length
和queue_length_bits
都是static const uint8_t
class常量。我可以用"O"
,"N"
,没办法。使用 static
、int8_t
与否没有区别。
如果我用 #define
替换上面的 static const uint8_t
定义,错误消息就会消失!
#define tail_mask ((rx1::queue_length-1) << rx1::queue_length_bits)
asm(
...
"andi r30, %0\n\t"
...
:
: "M" (tail_mask)
);
编译正常!
这让我很烦恼。为什么使用强制的 8 位无符号常量会在强制其成为... 8 位无符号常量的约束上产生错误消息?
郑重声明,我使用的是 avr-gcc
版本 7.1.0.
传递给约束的值在这里应该是一个32位整数。当你使用 #define 时你会得到什么,因为它被静默地提升为预期的类型。同样,使用 int 或 unsigned 作为 tail_mask 值也可以。奇怪的是我经历了 documentation 的几个版本,但没有发现 M 约束参数不能是 uint8_t 或类似的证据。