Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

Hi,

I know that Global Variables are a no no in Brew, but what about static global variables?

Hello nle,
I donot think brew supports any static global variables.

Hello nle,
I donot think brew supports any static global variables.

when you ask 'static' what do you mean ?
In C static means change the scope of a variable or function.
In english static means doesn't move.
'static global variable' theres no such thing*, if its static its not global, if you meant const and not static, then its not a variable.
*except in the final executable where a local static variable has a static modifier and its stored in the global data area, but its still not global to the program, its just persistant.
What you probably mean is 'const' ie constant, which means doesn't change.
Theres a lot of confusion over what brew can and can't support.
You can use file or globally scoped data that is READ ONLY in both data *and* address fixup/relocation.
so
const int foo[]={1,2,3,4}; at global, file scope is ok
You cannot use global/file scoped data thats variable or requires an address fixup.
You cannot use the static keyword to alter the scope of a function auto variable
and the important part why is that it makes it persistant across the execution of the program, thus effectively a global variable (even though its only scoped at the function level its defined in, but its stored in the same place as other global variables). ie
foo()
{
static int bar; // can't do this

also as another poster was asking recently if you create a const array of pointers to other const objects, (his code was incorrect which was )
typedef struct {e1,...e10} refTable;
const refTable myTable1 = {some values here...}
const refTable myTable2 = {...}
...
typedef const refTable* prefTable;
and,
prefTable listTable[20]={&myTable1, &myTable2,...};
there are two problems with this that stop it working with brew, one is fixable, one is not. The first being that the person doesn't know C well enough, and although they think thats a const array of pointers, it isn't its defined as being variable or read/write. The second is that even when its correctly defined and ends up being const it still won't work, because it will needs global address pointer relocations/fixups, or as its normally referred too, non position independant.
This is where the term ROPI comes in, READ ONLY & POSITION INDEPENDANT, if it doesn't meet both of these requirements, it won't work.
if you get stuck, the simple way to find out whats working and whats not, is to use the compiler and the linker with the ropi options *and* a MAP file, both of these together will tell you exactly where the problem lies. I'd run through an example but i have to dash, the missus is breathing down my neck, so maybe i'll get time later to add one. *whip crack* ;)
let the compiler do the work
Quote:
armcc -cpu ARM7TDMI -apcs /ropi/interwork test.c
Sample of incorrect code
typedef struct {
int e1;
int e2;
refTable;
const refTable myTable1 = {10,20};
const refTable myTable2 = {20,10};
typedef const refTable(*prefTable);
prefTable listTable[20]={&myTable1, &myTable2};
int main()
{
return 0;

will generate
Quote:
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable1' may cause link failure -ropi
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable2' may cause link failure -ropi
test.c: 2 warnings, 0 errors, 0 serious errors
the linker says
Quote:
Error: L6248E: test.o(.data) in ABSOLUTE region 'ER_RW' cannot have address/offs
et type relocation to myTable1 in PI region 'ER_RO'.
Error: L6248E: test.o(.data) in ABSOLUTE region 'ER_RW' cannot have address/offs
et type relocation to myTable2 in PI region 'ER_RO'.
Finished: 0 information, 0 warning and 2 error messages.
ok lets fix the code so its really const, which is problem 1.
compiler says (its still warning us about the address relocation)
Quote:
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable1' may cause link failure -ropi
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable2' may cause link failure -ropi
test.c: 2 warnings, 0 errors, 0 serious errors
linker says, (notice its now ER_RO and not ER_RW which means its now 'global const data' which some people have been saying is ok, but as you can see its clearly not.)
Quote:
Error: L6248E: test.o(.constdata) in PI region 'ER_RO' cannot have address type
relocation to myTable1 in PI region 'ER_RO'.
Error: L6248E: test.o(.constdata) in PI region 'ER_RO' cannot have address type
relocation to myTable2 in PI region 'ER_RO'.
So there you have it, you can have global const data, so long as it doesn't point to any kind of address, since that would make it no longer position independant and require a fix up at runtime.
so to recap
anything that has a constant value that isn't derived from the address of another data element or function is ok, anything that is global or file scope and variable including static modifiers on function auto variables isn't ok.
Its not whats in the data , its what its derived from and whether or not its read only.
// not ok
void *foo;
main(){}
//' ok
const int foo =1 ;
main(){}
// not ok
const void *ptr = &ptr
main(){}
// not ok
func()
{
static int foo;

main(){}
Interestingly i've noticed that armcc with ropi on can miss some problems, if you recompile with -S option to generate an asm output file , the assembler warns you about the missed problems, at least with ADS 1.2, i didn't check 1.1
YMMV, check it yourself, this is mostly typed in code, so it may have typo's, if you've ever talked to me on yahoo IM , you'll know what i mean

when you ask 'static' what do you mean ?
In C static means change the scope of a variable or function.
In english static means doesn't move.
'static global variable' theres no such thing*, if its static its not global, if you meant const and not static, then its not a variable.
*except in the final executable where a local static variable has a static modifier and its stored in the global data area, but its still not global to the program, its just persistant.
What you probably mean is 'const' ie constant, which means doesn't change.
Theres a lot of confusion over what brew can and can't support.
You can use file or globally scoped data that is READ ONLY in both data *and* address fixup/relocation.
so
const int foo[]={1,2,3,4}; at global, file scope is ok
You cannot use global/file scoped data thats variable or requires an address fixup.
You cannot use the static keyword to alter the scope of a function auto variable
and the important part why is that it makes it persistant across the execution of the program, thus effectively a global variable (even though its only scoped at the function level its defined in, but its stored in the same place as other global variables). ie
foo()
{
static int bar; // can't do this

also as another poster was asking recently if you create a const array of pointers to other const objects, (his code was incorrect which was )
typedef struct {e1,...e10} refTable;
const refTable myTable1 = {some values here...}
const refTable myTable2 = {...}
...
typedef const refTable* prefTable;
and,
prefTable listTable[20]={&myTable1, &myTable2,...};
there are two problems with this that stop it working with brew, one is fixable, one is not. The first being that the person doesn't know C well enough, and although they think thats a const array of pointers, it isn't its defined as being variable or read/write. The second is that even when its correctly defined and ends up being const it still won't work, because it will needs global address pointer relocations/fixups, or as its normally referred too, non position independant.
This is where the term ROPI comes in, READ ONLY & POSITION INDEPENDANT, if it doesn't meet both of these requirements, it won't work.
if you get stuck, the simple way to find out whats working and whats not, is to use the compiler and the linker with the ropi options *and* a MAP file, both of these together will tell you exactly where the problem lies. I'd run through an example but i have to dash, the missus is breathing down my neck, so maybe i'll get time later to add one. *whip crack* ;)
let the compiler do the work
Quote:
armcc -cpu ARM7TDMI -apcs /ropi/interwork test.c
Sample of incorrect code
typedef struct {
int e1;
int e2;
refTable;
const refTable myTable1 = {10,20};
const refTable myTable2 = {20,10};
typedef const refTable(*prefTable);
prefTable listTable[20]={&myTable1, &myTable2};
int main()
{
return 0;

will generate
Quote:
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable1' may cause link failure -ropi
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable2' may cause link failure -ropi
test.c: 2 warnings, 0 errors, 0 serious errors
the linker says
Quote:
Error: L6248E: test.o(.data) in ABSOLUTE region 'ER_RW' cannot have address/offs
et type relocation to myTable1 in PI region 'ER_RO'.
Error: L6248E: test.o(.data) in ABSOLUTE region 'ER_RW' cannot have address/offs
et type relocation to myTable2 in PI region 'ER_RO'.
Finished: 0 information, 0 warning and 2 error messages.
ok lets fix the code so its really const, which is problem 1.
compiler says (its still warning us about the address relocation)
Quote:
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable1' may cause link failure -ropi
"test.c", line 11: Warning: C3449W: static initialisation of 'listTable' using a
ddress of 'myTable2' may cause link failure -ropi
test.c: 2 warnings, 0 errors, 0 serious errors
linker says, (notice its now ER_RO and not ER_RW which means its now 'global const data' which some people have been saying is ok, but as you can see its clearly not.)
Quote:
Error: L6248E: test.o(.constdata) in PI region 'ER_RO' cannot have address type
relocation to myTable1 in PI region 'ER_RO'.
Error: L6248E: test.o(.constdata) in PI region 'ER_RO' cannot have address type
relocation to myTable2 in PI region 'ER_RO'.
So there you have it, you can have global const data, so long as it doesn't point to any kind of address, since that would make it no longer position independant and require a fix up at runtime.
so to recap
anything that has a constant value that isn't derived from the address of another data element or function is ok, anything that is global or file scope and variable including static modifiers on function auto variables isn't ok.
Its not whats in the data , its what its derived from and whether or not its read only.
// not ok
void *foo;
main(){}
//' ok
const int foo =1 ;
main(){}
// not ok
const void *ptr = &ptr
main(){}
// not ok
func()
{
static int foo;

main(){}
Interestingly i've noticed that armcc with ropi on can miss some problems, if you recompile with -S option to generate an asm output file , the assembler warns you about the missed problems, at least with ADS 1.2, i didn't check 1.1
YMMV, check it yourself, this is mostly typed in code, so it may have typo's, if you've ever talked to me on yahoo IM , you'll know what i mean

how about:
func()
{
static const char foo[] = {1,2,3};

?

how about:
func()
{
static const char foo[] = {1,2,3};

?

Brew Elf2Mod tool permits use of global and static variables in BREW apps.

Brew Elf2Mod tool permits use of global and static variables in BREW apps.