register struct Flags {
unsigned char a:1;
} F ;
void set(void) {
F.a=1;
}
fails on compile with
bitsets.c:6: error 35: '&' illegal operand , address of register variable
bitsets.c:6: error 47: indirections to different types assignment
from type 'literal-unsigned-char'
to type 'void'
Compiling it without the "register" keyword is fine.
sdcc -v:
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.3 #4913 (Sep 13 2007) (UNIX)
Logged In: YES
user_id=888171
Originator: NO
I think this stems from the fact that SDCC internally changes a struct access to a pointer access and I don't think there is anyhing pic specific about it.
B.t.w. using 'register' on a global variable is kind of strange too.
Logged In: YES
user_id=846991
Originator: YES
It seems to work fine on the ds390 and z80, but doesn't work on avr:
bitsets.c:6: error 9: FATAL Compiler Internal Error in file 'gen.c' line number '4424' : pointer not in correct register
if that helps.
'register' on a global variable would make more sense with the rest of the code, but this is a minimal example :-) On the pic16, it tries to force the variable into access RAM, which is slightly more efficient, ISTR
Logged In: YES
user_id=888171
Originator: NO
Indeed it works on all supported targets (mcs51, ds390, hc08, z80) and pic14. On pic16 it fails as well as on the unsupported avr. Therefor I set the category back to pic16.
The C specification prohibits taking the address of a variable with register strorage class. Therefor this is no bug.
6.5.3.2 Address and indirection operators
Constraints
1 The operand of the unary & operator shall be either a function designator, the result of a
[ ] or unary * operator, or an lvalue that designates an object that is not a bit-field and is
not declared with the register storage-class specifier.
And also this footnote:
101) The implementation may treat any register declaration simply as an auto declaration. However, whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary & operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1). Thus, the only operator that can be applied to an array declared with storage-class specifier register is sizeof.
The specification even prohibits 'register' for external definitions.
6.9 External definitions
Constraints
2 The storage-class specifiers auto and register shall not appear in the declaration
specifiers in an external declaration.
That's an .. interesting .. reading. The code as written doesn't take the address of the variable. The compiler internally takes the address of the variable. So the compiler is turning compliant code into non-compliant code internally, and failing it!
Oops, I'm sorry. I didn't look close enough to notice that there was no & in the original code.
Reverted back to open.
Diff: