C- Syntax to allocate Global variables to consecutive memory locations

difference.

Not being a language lawyer, either, I could conjur up an argument for keeping any data definition in c. The c source may not be the entire program and therefore the data definition may be required "elsewhere." I think c is much more this kind of "what you see is what you get" than c++ is, big picture. So I could argue that c definitions must stay, while accepting that c++ definitions can be optimized away.

Of course, I will defer to those who write the compilers and worry about these things.

Jon

Reply to
Jonathan Kirwan
Loading thread data ...

Whay you can do is make a global point and just set it to that address.

int *p; p = *(int *)&0x8000;

Reply to
MisterE

difference.

You're right in that in C constants can be used externally, and so could be referred to from another object file. This means that the constant definition must always be emitted by the compiler. One way is to place the unused definition in its own data section, so that it is trivial for the linker to spot as unused (no relocations to it) and remove.

Wilco

Reply to
Wilco Dijkstra

I too believe that this is correct standard C (perhaps there are issues if pointers and ints are not the same size?). However, the ordering of the fields within the struct, along with their sizes and alignments, is implementation dependant. A compiler may or may not add padding between fields, and can in fact re-order fields (for example, to make a more compact struct). Whether that is a problem or not depends on the requirements.

Reply to
David Brown

pointers and

Sure, you would need to be careful if you want your program to be portable, eg. use a long (or in C99 intptr_t), but it works fine.

and

padding between

struct).

Yes, this stuff is implementation dependent, but there is only one reasonable option in most cases (ie. align to natural alignment). As a result, structure layout is almost always the same if integer sizes are. Bitfields are generally fine too (except for enum bitfields - even the latest VC++ still implements them totally incorrectly).

The same argument applies to other issues like signed rightshift or

2-complements arithmetic. It is completely standard to assume both of these, and all compilers do the right thing. I often told language lawyers who wanted to add features that break these de-facto assumptions that they must personally deal with all the support queries from customers whose programs suddenly stop working as a result... That worked :-)

Wilco

Reply to
Wilco Dijkstra

pointers and

and

padding between

struct).

That's not true if you are looking for portability in the embedded world

- you can't assume that fields will be given their natural alignment. A compiler for a 16-bit micro will probably align 32-bit data on 16-bit boundaries, and an 8-bit micro will align everything on 8-bit. So you have to be careful there.

Bitfields are even worse. Some compilers will allocate bits from the most significant bit, although most start at the least significant bits. Standard C will, I believe, allocate a whole int for the bitfield, while some compilers (like gcc) allow bitfield types to be smaller than an int, and allocate only as much space as is needed for that type (i.e., a filed declared "short int x : 2" will be placed in a "short" field, not an "int" field). VC++ is a particularly good example of the non-portability of bitfields - the ordering of bitfields was changed from MSB to LSB between versions of VC++. That's not to say bitfields are bad - you just have to be aware of the issues.

Reply to
David Brown

Jon,

The actual syntax is

. . . @ integer_constant_expression

so

#define MYLOC &opq+29

int abc @ MYLOC;

is legal

It is possible to define MYLOC at link time meaning that the location of abc can be defined at link time.

This may only partly answer the question because we allow conditional compiles be evaluated at link time as well. This happens as a side effect of compiling to intermediate code objects. After the linker organizes the objects into an application the code full application optimized.

w..

-- Walter Banks Byte Craft Limited

1 519 888 6911
formatting link
snipped-for-privacy@bytecraft.com
Reply to
Walter Banks

In Byte Craft's linkers we allow link time #defines to be part of the linker script or included into the linker script (#defines with the same syntax as C defines) I think this would accomplish what you are looking for.

This is not in the context of ISO language definitions.

w..

-- Walter Banks Byte Craft Limited

1 519 888 6911
formatting link
snipped-for-privacy@bytecraft.com
Reply to
Walter Banks

pointers

sizes and

padding

compact

can't

16-bit micro

align

True, alignment is often different between 8, 16 and 32-bit systems, but so are integer sizes. Within architectures of the same bitsize there is far less variation. However it is possible to overalign fields if necessary or avoid relying on alignment completely (by allocating fields from largest to smallest).

significant

Allocating bitfields the wrong way around is a bad idea. It becomes particularly challenging if you have multiple container sizes and also mix with non-bitfields... I worked on a compiler that claimed to support them, but it only worked in the most basic cases, so I removed it in order to stop the significant support burden it produced.

Only old C standards do (C89 and earlier), and even then it was implementation defined.

int, and

"short

Correct. This has been the defacto standard on most embedded compilers for a long time, and it finally made it in C99 and C++.

ordering of

say

Yes, even the latest C standard doesn't specify bitfields properly, so it is a small wonder bitfields can be portable at all... The ARM EABI gives an exact specification so that compilers behave identically (this includes a mathematical definition of bitfield allocation I invented, and solves issues like zero-sized and oversized bitfields, signedness and enums). One can hope the C/C++ standards will catch up one good day...

Wilco

Reply to
Wilco Dijkstra

Close, but no cigar you've got both an extra '*' and an extra '&'.

ITYM

int *p = (int*)0x8000;

It's almost always more efficient if you do it this way:

#define p ((int*)0x8000)

That doesn't take up any storage for 'p' and allows the compiler to avoid loading and de-referencing the pointer.

Of course, the OP's problem is better solved by declaring his "certain variables" as residing in a unique memory section and then telling the linker where to put that memory section.

If he wants them in a particular order within that section, then he needs to use a structure.

--
Grant Edwards                   grante             Yow!  Hello? Enema
                                  at               Bondage? I'm calling
                               visi.com            because I want to be happy,
                                                   I guess...
Reply to
Grant Edwards

According to K&R, the compiler may not re-order struct fields. Quoting from §8.5:

Within a structure, the objects declared have addresses which increase as their declarations are read left to right.

The current working-version of ISO 9899 is available at

formatting link

Quoting from §6.7.2.1 Structure and union specifiers

¶13 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase win the order in which they are declared.

Which C standard allows structure fields to be re-ordered by the compiler?

All compilers I've ever used provided a way to control padding within structures. Since this is obviously platform-specific code, I don't consider that too evil.

--
Grant Edwards                   grante             Yow!  I'm meditating on
                                  at               the FORMALDEHYDE and the
                               visi.com            ASBESTOS leaking into my
                                                   PERSONAL SPACE!!
Reply to
Grant Edwards

Note: above sentence contains three times the word 'might'.

The word _might_ occurs three times in the quoted sentence. You are reasoning as if at least one of them is a _must_, which is not correct.

Rob

Reply to
Rob Windgassen

No, that's not at all what I'm arguing. The point is this: if a piece of code has any possibility of leading to undefined behaviour, then its behaviour is rather obviouslz not "defined". Which means that such a piece of code exhibits undefined behaviour. It's as simple as that.

Behaviour of a piece of code is either defined (by the language standard or the implementation), or it's not. Tertium non datur.

Reply to
Hans-Bernhard Bröker

David Brown wrote about this:

It's not. The second code line above has an implementation-defined effect. One possible result is that "ptr" ends up holding a trap representation. If it does (and there's *no* standard C way of being sure it doesn't), then the third line, dereferencing a pointer holding a trap representation, causes undefined behaviour. Code that causes undefined behaviour can not possibly be called "correct" by any useful interpretation of that term.

For those who insist on examples instead of standard-ese: there's nothing to stop a platform from simply not having any addressable memory address (void *)0x8000. And there sure as manure is no requirement for this memory, if it exists, to be _writable_.

The above code is about as far from being "correct standard C" as any piece of code can be, while still passing through a typical C compiler.

Correct

A lot of people think that, but they're wrong. The Standard doesn't say so out loud but no, a C compiler is not allowed to change the order of fields inside a structure from that found in the source.

Reply to
Hans-Bernhard Bröker

significant

Actually no. It cannot be a bad idea for the brutally simple reason that there is no "wrong way round". There's no "right way round" either. What there is are two major possibilities, and a whole realm of more-or-less perverse mixes between them. They're all different, but none of them is "wrong".

Reply to
Hans-Bernhard Bröker

Actually it does say "out loud" that compilers must not change the order of fields inside a structure. See my previous posting for the specific paragraphs (from both K&R and ISO-9899).

Unless that's not considered "out loud" -- though I don't see how that language could mean anything else...

--
Grant Edwards                   grante             Yow!  I just remembered
                                  at               something about a TOAD!
                               visi.com
Reply to
Grant Edwards

One problem being that neither of those truly is "the" Standard the majority of embedded work has to rely on, which still is C-90. K&R stopped being the standard when the first actual standard arrived, and C99 is often still a castle in the sky.

The wording about increasing order was only added in C99 unless I misremember worse than usual. There used to be only the statement about pointer casts between a struct and an extended version of itself with additional elements added only at the end, being allowed. The sequential-ordering requirement follows from that, but this fact was hidden a bit too well.

Reply to
Hans-Bernhard Bröker

Ah, I was wondering about that. I don't currently have access to a copy of the C90 spec. I assumed that something which was stately virtually identicallyin K&R and C99 would also be in C90.

I find it very odd that they would take what was a clearly worded requirement in K&R, remove it, then put it back. On second thought, when I recall my experiences with standards processes, I guess it's not all that odd...

--
Grant Edwards                   grante             Yow!  A dwarf is passing
                                  at               out somewhere in Detroit!
                               visi.com
Reply to
Grant Edwards

In 6.5.2.1, C90 says, "Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared." This is the identical wording of C99, 6.7.2.1.

--
John W. Temples, III
Reply to
John Temples

I had found a refence somewhere to 6.5.2.1 in regards to this topic, but the poster didn't say what spec he was citing. Looks like it was C90.

--
Grant Edwards                   grante             Yow!  SHHHH!! I hear SIX
                                  at               TATTOOED TRUCK-DRIVERS
                               visi.com            tossing ENGINE BLOCKS into
                                                   empty OIL DRUMS...
Reply to
Grant Edwards

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.