www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - int always 32 bits on all platforms?

reply "AJ" <aj nospam.net> writes:
How can/does D guarantee that "int" will always be 32 bits on all platforms?
Does this mean that D won't work on some platforms? Why is integer width so
ambiguous in C/C++? (I am using "platform" as equivalent to 
CPU+OS+compiler).
Oct 21 2009
next sibling parent reply BCS <none anon.com> writes:
Hello aJ,

 How can/does D guarantee that "int" will always be 32 bits on all
 platforms? Does this mean that D won't work on some platforms?

D is not built for 8 or 16 bit systems. However 32 bit math can be done on a 16 bit CPU, it's just slow. In the other direction, 32 bit math (and 16 and 8 bit) can be done on a 64 bit CPU so that's not a problem. If you really want the machine word size (and expecting code that does that to port is foolish) use size_t.
 Why is
 integer width so ambiguous in C/C++? (I am using "platform" as
 equivalent to CPU+OS+compiler).
 

In C IIRC the rule is: "native text item" == char <= short <= int <= long. This is a result of legacy issues from WAY back when (I think).
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"BCS" <none anon.com> wrote in message 
news:a6268ffbadb8cc20772570e4f0 news.digitalmars.com...
 Hello aJ,

 How can/does D guarantee that "int" will always be 32 bits on all
 platforms? Does this mean that D won't work on some platforms?

D is not built for 8 or 16 bit systems. However 32 bit math can be done on a 16 bit CPU, it's just slow. In the other direction, 32 bit math (and 16 and 8 bit) can be done on a 64 bit CPU so that's not a problem.

I wasn't thinking about math issues, but rather struct field alignment/portability, and platform alignment requirements for basic types, issues. I'm guessing that it is all worked out by the compiler, so that makes the development of a compiler more difficult, if so, but how much more difficult? A simple example or description of how this is done would really be great. (BTW, this is definitely an area where I would approve of more language implementation complexity for the great strides in programming efficiency (and fun!) it gives).
Oct 21 2009
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
AJ Wrote:

 
 "BCS" <none anon.com> wrote in message 
 news:a6268ffbadb8cc20772570e4f0 news.digitalmars.com...
 Hello aJ,

 How can/does D guarantee that "int" will always be 32 bits on all
 platforms? Does this mean that D won't work on some platforms?

D is not built for 8 or 16 bit systems. However 32 bit math can be done on a 16 bit CPU, it's just slow. In the other direction, 32 bit math (and 16 and 8 bit) can be done on a 64 bit CPU so that's not a problem.

I wasn't thinking about math issues, but rather struct field alignment/portability, and platform alignment requirements for basic types, issues. I'm guessing that it is all worked out by the compiler, so that makes the development of a compiler more difficult, if so, but how much more difficult? A simple example or description of how this is done would really be great. (BTW, this is definitely an area where I would approve of more language implementation complexity for the great strides in programming efficiency (and fun!) it gives).

In D, both type size and alignment have the same defaults on all platforms. If desired, alignment can be explicitly controlled with the align attribute. Similarly, use of specific types control sizes.
Oct 21 2009
next sibling parent BCS <none anon.com> writes:
Hello Jason,

 In D, both type size and alignment have the same defaults on all
 platforms. If desired, alignment can be explicitly controlled with the
 align attribute. Similarly, use of specific types control sizes.
 

Ummm? IIRC, struct alignment follows the lead of the "native compiler" for the given system. That is, type size issues aside, structs without align directive can be passed from C to D by default.
Oct 21 2009
prev sibling next sibling parent reply "AJ" <aj nospam.net> writes:
"Jason House" <jason.james.house gmail.com> wrote in message 
news:hbo2ru$2p6j$1 digitalmars.com...
 AJ Wrote:

 "BCS" <none anon.com> wrote in message
 news:a6268ffbadb8cc20772570e4f0 news.digitalmars.com...
 Hello aJ,

 How can/does D guarantee that "int" will always be 32 bits on all
 platforms? Does this mean that D won't work on some platforms?

D is not built for 8 or 16 bit systems. However 32 bit math can be done on a 16 bit CPU, it's just slow. In the other direction, 32 bit math (and 16 and 8 bit) can be done on a 64 bit CPU so that's not a problem.

I wasn't thinking about math issues, but rather struct field alignment/portability, and platform alignment requirements for basic types, issues. I'm guessing that it is all worked out by the compiler, so that makes the development of a compiler more difficult, if so, but how much more difficult? A simple example or description of how this is done would really be great. (BTW, this is definitely an area where I would approve of more language implementation complexity for the great strides in programming efficiency (and fun!) it gives).

In D, both type size and alignment have the same defaults on all platforms.

That must be some kind of magic considering that only some platforms require alignment on certain (word, dword, etc.) boundaries.
 If desired, alignment can be explicitly controlled with the align 
 attribute. Similarly, use of specific types control sizes.

Tell me, in D, can I have all the members of the following struct be byte-aligned and still access and use the members directly on all platforms without some kind of "seqfault"(?): struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue }; I don't see how the answer could be "yes" to the above. Now the following stands a chance at working across platforms (with D, not with C/C++) though: struct CDE { int32 c; int32 d; int64 e; // properly aligned, probably }; So did I just "summarize" the extent to which guaranteed basic type widths can be exploited, in that the design of ABC is always a "no no" and the design of CDE is very likely to work reliably across a wide range of designated platforms?
Oct 21 2009
parent reply BCS <none anon.com> writes:
Hello aJ,

 In D, both type size and alignment have the same defaults on all
 platforms.
 

require alignment on certain (word, dword, etc.) boundaries.

OK scratch alignment, I don't know what I was thinking there.
 
 If desired, alignment can be explicitly controlled with the align
 attribute. Similarly, use of specific types control sizes.
 

byte-aligned and still access and use the members directly on all platforms without some kind of "seqfault"(?):

Clearly if your CPU doesn't like to unaligned reads you are going to have problems with unaligned data members. In that cases you have several options: 1) if you don't really care much about the offsets, let DMD do it's thing 2) if you must have some given offsets, force it with align and live with the results because you're sunk 3) if you just need the same offset on a set of know systems, manually find something that works and force that with align (no compiler could help you here unless it know about all the system you care about) 4) if you just need the same offset on all system and you don't know what system will be used, see 2 because you're sunk.
 So did I just "summarize" the extent to which guaranteed basic type
 widths can be exploited, in that the design of ABC is always a "no no"
 and the design of CDE is very likely to work reliably across a wide
 range of designated platforms?
 

I'm not very up on these issues but in short, you can let DMD do it's thing and get good result on any given system or you can force some alignment and get binary compatibility across systems. This is the same as in C. What D gives you (or takes away) is issues about int being one size on one system and another size of a different system.
Oct 22 2009
parent "AJ" <aj nospam.net> writes:
"BCS" <none anon.com> wrote in message 
news:a6268ffbc2f8cc21197db85ef2 news.digitalmars.com...
 Hello aJ,

 In D, both type size and alignment have the same defaults on all
 platforms.

require alignment on certain (word, dword, etc.) boundaries.

OK scratch alignment, I don't know what I was thinking there.
 If desired, alignment can be explicitly controlled with the align
 attribute. Similarly, use of specific types control sizes.

byte-aligned and still access and use the members directly on all platforms without some kind of "seqfault"(?):

Clearly if your CPU doesn't like to unaligned reads you are going to have problems with unaligned data members. In that cases you have several options: 1) if you don't really care much about the offsets, let DMD do it's thing 2) if you must have some given offsets, force it with align and live with the results because you're sunk 3) if you just need the same offset on a set of know systems, manually find something that works and force that with align (no compiler could help you here unless it know about all the system you care about) 4) if you just need the same offset on all system and you don't know what system will be used, see 2 because you're sunk.

As I thought, I want hardware standardization. Save for hell freezing over, #3 is what I do (and catch a lot of flak for also).
 So did I just "summarize" the extent to which guaranteed basic type
 widths can be exploited, in that the design of ABC is always a "no no"
 and the design of CDE is very likely to work reliably across a wide
 range of designated platforms?

I'm not very up on these issues but in short, you can let DMD do it's thing and get good result on any given system or you can force some alignment and get binary compatibility across systems. This is the same as in C. What D gives you (or takes away) is issues about int being one size on one system and another size of a different system.

Understood.
Oct 22 2009
prev sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Jason House wrote:
 In D, both type size and alignment have the same defaults on all
 platforms.

Not exactly true. The alignment defaults to what the native C compiler does on a particular platform.
Oct 21 2009
prev sibling parent reply BCS <none anon.com> writes:
Hello aJ,

 "BCS" <none anon.com> wrote in message
 news:a6268ffbadb8cc20772570e4f0 news.digitalmars.com...
 
 Hello aJ,
 
 How can/does D guarantee that "int" will always be 32 bits on all
 platforms? Does this mean that D won't work on some platforms?
 

done on a 16 bit CPU, it's just slow. In the other direction, 32 bit math (and 16 and 8 bit) can be done on a 64 bit CPU so that's not a problem.


OK
 but rather struct field
 alignment/portability, and platform alignment requirements for basic
 types, issues.

Unless you say otherwise, the compiler is free to align struct however it wants (this is true in C but there are conventions) and in general you can't expect it to do the same for different system (again, ditto re C) OTOH I'm not sure how that links into int being the same size all over. If anything that should make these issue less of a problem.
 I'm guessing that it is all worked out by the compiler,
 so that makes the development of a compiler more difficult, if so, but
 how much more difficult? A simple example or description of how this
 is done would really be great. (BTW, this is definitely an area where
 I would approve of more language implementation complexity for the
 great strides in programming efficiency (and fun!) it gives).

Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"BCS" <none anon.com> wrote in message 
news:a6268ffbaf38cc207c6738826c news.digitalmars.com...
 Hello aJ,

 "BCS" <none anon.com> wrote in message
 news:a6268ffbadb8cc20772570e4f0 news.digitalmars.com...

 Hello aJ,

 How can/does D guarantee that "int" will always be 32 bits on all
 platforms? Does this mean that D won't work on some platforms?

done on a 16 bit CPU, it's just slow. In the other direction, 32 bit math (and 16 and 8 bit) can be done on a 64 bit CPU so that's not a problem.


OK
 but rather struct field
 alignment/portability, and platform alignment requirements for basic
 types, issues.

Unless you say otherwise, the compiler is free to align struct however it wants (this is true in C but there are conventions) and in general you can't expect it to do the same for different system (again, ditto re C) OTOH I'm not sure how that links into int being the same size all over. If anything that should make these issue less of a problem.

I would think so. Anyway, what I find compelling about guaranteed widths is the potential to eliminate alignment and padding issues (that is, be able to control it with confidence across platforms as one already can on a single platform via compiler pragmas or cmdline switches).
 I'm guessing that it is all worked out by the compiler,
 so that makes the development of a compiler more difficult, if so, but
 how much more difficult? A simple example or description of how this
 is done would really be great. (BTW, this is definitely an area where
 I would approve of more language implementation complexity for the
 great strides in programming efficiency (and fun!) it gives).


Oct 21 2009
parent reply BCS <none anon.com> writes:
Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).
 

Ah! I thought you were taking issue with something. D has that and gets most of the porting stuff to work.
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"BCS" <none anon.com> wrote in message 
news:a6268ffbb0a8cc20817fe1f1c2 news.digitalmars.com...
 Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).

Ah! I thought you were taking issue with something. D has that and gets most of the porting stuff to work.

It does? Get this to work on "all" platforms: struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };
Oct 21 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"AJ" <aj nospam.net> wrote in message news:hboaeu$5sk$1 digitalmars.com...
 "BCS" <none anon.com> wrote in message 
 news:a6268ffbb0a8cc20817fe1f1c2 news.digitalmars.com...
 Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).

Ah! I thought you were taking issue with something. D has that and gets most of the porting stuff to work.

It does? Get this to work on "all" platforms: struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

// Guarantee packed on all platforms align() struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue }; // Guarantee 64-bit alignment on a, b, and c on all platforms align(8) struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:hbonbp$to1$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message news:hboaeu$5sk$1 digitalmars.com...
 "BCS" <none anon.com> wrote in message 
 news:a6268ffbb0a8cc20817fe1f1c2 news.digitalmars.com...
 Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).

Ah! I thought you were taking issue with something. D has that and gets most of the porting stuff to work.

It does? Get this to work on "all" platforms: struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

// Guarantee packed on all platforms align() struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

Well I can do the same thing with pragma or compiler switch in C++. It doesn't mean that thing will work if 32-bit ints have to be aligned on 32-bit boundaries. While nice to have one syntax to do that, it doesn't fix the "problem" (which I haven't expressed correctly probably). What good is a packed structure that has misaligned data members for the platform?
 // Guarantee 64-bit alignment on a, b, and c on all platforms
 align(8) struct ABC
 {
    byte a;
    int b; // may be improperly aligned on some platforms
    int64 c; // same issue
 };

 

Oct 21 2009
next sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
AJ wrote:
 "Nick Sabalausky" <a a.a> wrote in message 
 news:hbonbp$to1$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message news:hboaeu$5sk$1 digitalmars.com...
 "BCS" <none anon.com> wrote in message 
 news:a6268ffbb0a8cc20817fe1f1c2 news.digitalmars.com...
 Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).

most of the porting stuff to work.

struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

align() struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

Well I can do the same thing with pragma or compiler switch in C++. It doesn't mean that thing will work if 32-bit ints have to be aligned on 32-bit boundaries. While nice to have one syntax to do that, it doesn't fix the "problem" (which I haven't expressed correctly probably). What good is a packed structure that has misaligned data members for the platform?

struct ABC { version (RequireAlign4) align(4) byte a; int b; int64 c; }
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message 
news:hbou95$1ald$1 digitalmars.com...
 AJ wrote:
 "Nick Sabalausky" <a a.a> wrote in message 
 news:hbonbp$to1$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message 
 news:hboaeu$5sk$1 digitalmars.com...
 "BCS" <none anon.com> wrote in message 
 news:a6268ffbb0a8cc20817fe1f1c2 news.digitalmars.com...
 Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).

gets most of the porting stuff to work.

struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

align() struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

Well I can do the same thing with pragma or compiler switch in C++. It doesn't mean that thing will work if 32-bit ints have to be aligned on 32-bit boundaries. While nice to have one syntax to do that, it doesn't fix the "problem" (which I haven't expressed correctly probably). What good is a packed structure that has misaligned data members for the platform?

struct ABC { version (RequireAlign4) align(4) byte a; int b; int64 c; }

Please 'splain the above.
Oct 22 2009
parent "Nick Sabalausky" <a a.a> writes:
"AJ" <aj nospam.net> wrote in message news:hbp85j$238g$1 digitalmars.com...
 "Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message 
 news:hbou95$1ald$1 digitalmars.com...
 AJ wrote:
 "Nick Sabalausky" <a a.a> wrote in message 
 news:hbonbp$to1$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message 
 news:hboaeu$5sk$1 digitalmars.com...
 "BCS" <none anon.com> wrote in message 
 news:a6268ffbb0a8cc20817fe1f1c2 news.digitalmars.com...
 Hello aJ,

 I would think so. Anyway, what I find compelling about guaranteed
 widths is the potential to eliminate alignment and padding issues
 (that is, be able to control it with confidence across platforms as
 one already can on a single platform via compiler pragmas or cmdline
 switches).

gets most of the porting stuff to work.

struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

align() struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

Well I can do the same thing with pragma or compiler switch in C++. It doesn't mean that thing will work if 32-bit ints have to be aligned on 32-bit boundaries. While nice to have one syntax to do that, it doesn't fix the "problem" (which I haven't expressed correctly probably). What good is a packed structure that has misaligned data members for the platform?

struct ABC { version (RequireAlign4) align(4) byte a; int b; int64 c; }

Please 'splain the above.

http://www.digitalmars.com/d/1.0/attribute.html#align http://www.digitalmars.com/d/1.0/version.html#version http://dictionary.reference.com/browse/explain?r=75
Oct 22 2009
prev sibling parent reply BCS <none anon.com> writes:
Hello aJ,

 Well I can do the same thing with pragma or compiler switch in C++.
 It doesn't mean that thing will work if 32-bit ints have to be aligned
 on 32-bit boundaries. While nice to have one syntax to do that, it
 doesn't fix the "problem" (which I haven't expressed correctly
 probably). What good is a packed structure that has misaligned data
 members for the platform?

You end up with mutually exclusive goals for different systems: align to (depending on the CPU) 8/16/32/64 bits and make it compact. You just can't have both in all cases. Generally I would expect you get one of three cases: 1) you need to ship binary struct from one system to another so you need to match a given layout from a different system (in this case avoiding misaligned data is a matter of luck), 2) you never ship the data out of the process (just skip all the align directives and let DMD align stuff correctly as, I think, it does by default) or 3) you need packed data (uses align to align on 8 bits)
Oct 22 2009
parent "AJ" <aj nospam.net> writes:
"BCS" <none anon.com> wrote in message 
news:a6268ffbc0a8cc210e3ccb7da8 news.digitalmars.com...
 Hello aJ,

 Well I can do the same thing with pragma or compiler switch in C++.
 It doesn't mean that thing will work if 32-bit ints have to be aligned
 on 32-bit boundaries. While nice to have one syntax to do that, it
 doesn't fix the "problem" (which I haven't expressed correctly
 probably). What good is a packed structure that has misaligned data
 members for the platform?

You end up with mutually exclusive goals for different systems: align to (depending on the CPU) 8/16/32/64 bits and make it compact. You just can't have both in all cases.

I knew that, I just wanted to be sure I did.
 Generally I would expect you get one of three cases: 1) you need to ship 
 binary struct from one system to another so you need to match a given 
 layout from a different system (in this case avoiding misaligned data is a 
 matter of luck), 2) you never ship the data out of the process (just skip 
 all the align directives and let DMD align stuff correctly as, I think, it 
 does by default) or 3) you need packed data (uses align to align on 8 
 bits)

#1 is Nirvana.
Oct 22 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
AJ wrote:
 How can/does D guarantee that "int" will always be 32 bits on all platforms?

The implementation on a platform must implement it that way.
 Does this mean that D won't work on some platforms?

You can make anything work on any platform - the tradeoffs are some may be too inefficient to be usable. For example, a PDP-10 has 36 bit words. I'd say a Ten isn't likely to get a D implementation.
 Why is integer width so ambiguous in C/C++? (I am using "platform" as
equivalent to 
 CPU+OS+compiler).

Because C was developed for 16 bit computers where 'int' was efficiently implemented as 16 bits.
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:hbo5il$2snd$5 digitalmars.com...
 AJ wrote:
 How can/does D guarantee that "int" will always be 32 bits on all 
 platforms?

The implementation on a platform must implement it that way.
 Does this mean that D won't work on some platforms?

You can make anything work on any platform

How do you make ABC below work on a platform that requires 32-bit integers to be aligned on 32-bit boundaries while keeping the layount and size of ABC the same as on a platform that has no such alignment requirement? struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };
Oct 21 2009
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"AJ" <aj nospam.net> wrote in message news:hboa9p$5md$1 digitalmars.com...
 "Walter Bright" <newshound1 digitalmars.com> wrote in message 
 news:hbo5il$2snd$5 digitalmars.com...
 AJ wrote:
 How can/does D guarantee that "int" will always be 32 bits on all 
 platforms?

The implementation on a platform must implement it that way.
 Does this mean that D won't work on some platforms?

You can make anything work on any platform

How do you make ABC below work on a platform that requires 32-bit integers to be aligned on 32-bit boundaries while keeping the layount and size of ABC the same as on a platform that has no such alignment requirement? struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

It can be done by using bitmasks and bit shifting on every access.
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:hbonj3$u34$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message news:hboa9p$5md$1 digitalmars.com...
 "Walter Bright" <newshound1 digitalmars.com> wrote in message 
 news:hbo5il$2snd$5 digitalmars.com...
 AJ wrote:
 How can/does D guarantee that "int" will always be 32 bits on all 
 platforms?

The implementation on a platform must implement it that way.
 Does this mean that D won't work on some platforms?

You can make anything work on any platform

How do you make ABC below work on a platform that requires 32-bit integers to be aligned on 32-bit boundaries while keeping the layount and size of ABC the same as on a platform that has no such alignment requirement? struct ABC { byte a; int b; // may be improperly aligned on some platforms int64 c; // same issue };

It can be done by using bitmasks and bit shifting on every access.

I had a feeling I was delving into "dangerous territory" (read, way too low level for me, but I wonder what the possibilities are). I have a feeling that I may be wanting hardware standardization because it can't be "solved" at the language level (?). I don't understand how using bitmasks and bit shifting on every access would work, the plausibility of it, and the cost (in execution time) of doing so.
Oct 21 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"AJ" <aj nospam.net> wrote in message news:hbor97$155c$1 digitalmars.com...
 "Nick Sabalausky" <a a.a> wrote in message 
 news:hbonj3$u34$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message 
 news:hboa9p$5md$1 digitalmars.com...
 How do you make ABC below work on a platform that requires 32-bit 
 integers to be aligned on 32-bit boundaries while keeping the layount 
 and size of ABC the same as on a platform that has no such alignment 
 requirement?

 struct ABC
 {
    byte a;
    int b; // may be improperly aligned on some platforms
    int64 c; // same issue
 };

It can be done by using bitmasks and bit shifting on every access.

I had a feeling I was delving into "dangerous territory" (read, way too low level for me, but I wonder what the possibilities are). I have a feeling that I may be wanting hardware standardization because it can't be "solved" at the language level (?). I don't understand how using bitmasks and bit shifting on every access would work

Normally, the compiler would turn this: myabc1.b = myabc2.b + 1; Into something like this: - move value at memory address xxxxx (myabc2.b) into cpu register - add 1 - move value in cpu register into memory address xxxxx (myabc1.b) If the compiler knows that myabc1.b and myabc2.b are not aligned in a way that the cpu can directly access, then what it would turn it into is something like: - move the values at the two memory addresses that myabc2.b straddles into cpu registers - use bit manipulation tricks to throw away myabc2.a and myabc2.c and compine the two parts of myabc2.b - add 1 - use bit manipulation tricks to split the value in the cpu register back into two parts, and mix in myabc1.a and myabc1.c - move the restulting values into the memory addresses that myabc1.b straddles
 the plausibility of it

It should always possible. Although references to the struct's members would probably be very tricky and require a lot of extra fancy work.
 and the cost (in execution time) of doing so.

Depends completely on the cpu, of course. In general though, it's quite a bit slower (a single fetch or store turns into at least two fetches/stores plus some bitmasking and shifting, maybe uses up extra registers, and would make less of the code fit in cache). But that's the price you pay for using packed structs like that on such a CPU. Or you could just use align(4) to guarantee 32-bit alignment on all fields for all cpus.
Oct 21 2009
parent reply "AJ" <aj nospam.net> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:hboui3$1bbt$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message 
 news:hbor97$155c$1 digitalmars.com...
 "Nick Sabalausky" <a a.a> wrote in message 
 news:hbonj3$u34$1 digitalmars.com...
 "AJ" <aj nospam.net> wrote in message 
 news:hboa9p$5md$1 digitalmars.com...
 How do you make ABC below work on a platform that requires 32-bit 
 integers to be aligned on 32-bit boundaries while keeping the layount 
 and size of ABC the same as on a platform that has no such alignment 
 requirement?

 struct ABC
 {
    byte a;
    int b; // may be improperly aligned on some platforms
    int64 c; // same issue
 };

It can be done by using bitmasks and bit shifting on every access.

I had a feeling I was delving into "dangerous territory" (read, way too low level for me, but I wonder what the possibilities are). I have a feeling that I may be wanting hardware standardization because it can't be "solved" at the language level (?). I don't understand how using bitmasks and bit shifting on every access would work

Normally, the compiler would turn this: myabc1.b = myabc2.b + 1; Into something like this: - move value at memory address xxxxx (myabc2.b) into cpu register - add 1 - move value in cpu register into memory address xxxxx (myabc1.b) If the compiler knows that myabc1.b and myabc2.b are not aligned in a way that the cpu can directly access, then what it would turn it into is something like: - move the values at the two memory addresses that myabc2.b straddles into cpu registers - use bit manipulation tricks to throw away myabc2.a and myabc2.c and compine the two parts of myabc2.b - add 1 - use bit manipulation tricks to split the value in the cpu register back into two parts, and mix in myabc1.a and myabc1.c - move the restulting values into the memory addresses that myabc1.b straddles

OK, thanks.
 the plausibility of it

It should always possible. Although references to the struct's members would probably be very tricky and require a lot of extra fancy work.

I should have used 'practicality' instead of 'plausibility'. So maybe not so practical (unless the concept is a real boon). (No, I don't know what a "boon" is either ;) ).
 and the cost (in execution time) of doing so.

Depends completely on the cpu, of course. In general though, it's quite a bit slower (a single fetch or store turns into at least two fetches/stores plus some bitmasking and shifting, maybe uses up extra registers, and would make less of the code fit in cache). But that's the price you pay for using packed structs like that on such a CPU. Or you could just use align(4) to guarantee 32-bit alignment on all fields for all cpus.

Yes, surely that is the way to go. Or... craft structs to align nicely in the first place and make the decision on which CPUs you want one set of code to run on: struct ABC { byte a; byte pad1; byte pad2; byte pad3; int b; // may be improperly aligned on some platforms int64 c; // same issue }
Oct 22 2009
parent reply KennyTM~ <kennytm gmail.com> writes:
On Oct 22, 09 17:31, AJ wrote:
 "Nick Sabalausky"<a a.a>  wrote in message
 news:hboui3$1bbt$1 digitalmars.com...
 "AJ"<aj nospam.net>  wrote in message
 news:hbor97$155c$1 digitalmars.com...
 "Nick Sabalausky"<a a.a>  wrote in message
 news:hbonj3$u34$1 digitalmars.com...
 "AJ"<aj nospam.net>  wrote in message
 news:hboa9p$5md$1 digitalmars.com...
 How do you make ABC below work on a platform that requires 32-bit
 integers to be aligned on 32-bit boundaries while keeping the layount
 and size of ABC the same as on a platform that has no such alignment
 requirement?

 struct ABC
 {
     byte a;
     int b; // may be improperly aligned on some platforms
     int64 c; // same issue
 };

It can be done by using bitmasks and bit shifting on every access.

I had a feeling I was delving into "dangerous territory" (read, way too low level for me, but I wonder what the possibilities are). I have a feeling that I may be wanting hardware standardization because it can't be "solved" at the language level (?). I don't understand how using bitmasks and bit shifting on every access would work

Normally, the compiler would turn this: myabc1.b = myabc2.b + 1; Into something like this: - move value at memory address xxxxx (myabc2.b) into cpu register - add 1 - move value in cpu register into memory address xxxxx (myabc1.b) If the compiler knows that myabc1.b and myabc2.b are not aligned in a way that the cpu can directly access, then what it would turn it into is something like: - move the values at the two memory addresses that myabc2.b straddles into cpu registers - use bit manipulation tricks to throw away myabc2.a and myabc2.c and compine the two parts of myabc2.b - add 1 - use bit manipulation tricks to split the value in the cpu register back into two parts, and mix in myabc1.a and myabc1.c - move the restulting values into the memory addresses that myabc1.b straddles

OK, thanks.
 the plausibility of it

It should always possible. Although references to the struct's members would probably be very tricky and require a lot of extra fancy work.

I should have used 'practicality' instead of 'plausibility'. So maybe not so practical (unless the concept is a real boon). (No, I don't know what a "boon" is either ;) ).
 and the cost (in execution time) of doing so.

Depends completely on the cpu, of course. In general though, it's quite a bit slower (a single fetch or store turns into at least two fetches/stores plus some bitmasking and shifting, maybe uses up extra registers, and would make less of the code fit in cache). But that's the price you pay for using packed structs like that on such a CPU. Or you could just use align(4) to guarantee 32-bit alignment on all fields for all cpus.

Yes, surely that is the way to go. Or... craft structs to align nicely in the first place and make the decision on which CPUs you want one set of code to run on: struct ABC { byte a; byte pad1; byte pad2; byte pad3; int b; // may be improperly aligned on some platforms int64 c; // same issue }

If data offset is really that important, you should use a bitfield.
Oct 22 2009
parent reply "AJ" <aj nospam.net> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:hbp924$24ht$1 digitalmars.com...
 On Oct 22, 09 17:31, AJ wrote:
 "Nick Sabalausky"<a a.a>  wrote in message
 news:hboui3$1bbt$1 digitalmars.com...
 "AJ"<aj nospam.net>  wrote in message
 news:hbor97$155c$1 digitalmars.com...
 "Nick Sabalausky"<a a.a>  wrote in message
 news:hbonj3$u34$1 digitalmars.com...
 "AJ"<aj nospam.net>  wrote in message
 news:hboa9p$5md$1 digitalmars.com...
 How do you make ABC below work on a platform that requires 32-bit
 integers to be aligned on 32-bit boundaries while keeping the layount
 and size of ABC the same as on a platform that has no such alignment
 requirement?

 struct ABC
 {
     byte a;
     int b; // may be improperly aligned on some platforms
     int64 c; // same issue
 };

It can be done by using bitmasks and bit shifting on every access.

I had a feeling I was delving into "dangerous territory" (read, way too low level for me, but I wonder what the possibilities are). I have a feeling that I may be wanting hardware standardization because it can't be "solved" at the language level (?). I don't understand how using bitmasks and bit shifting on every access would work

Normally, the compiler would turn this: myabc1.b = myabc2.b + 1; Into something like this: - move value at memory address xxxxx (myabc2.b) into cpu register - add 1 - move value in cpu register into memory address xxxxx (myabc1.b) If the compiler knows that myabc1.b and myabc2.b are not aligned in a way that the cpu can directly access, then what it would turn it into is something like: - move the values at the two memory addresses that myabc2.b straddles into cpu registers - use bit manipulation tricks to throw away myabc2.a and myabc2.c and compine the two parts of myabc2.b - add 1 - use bit manipulation tricks to split the value in the cpu register back into two parts, and mix in myabc1.a and myabc1.c - move the restulting values into the memory addresses that myabc1.b straddles

OK, thanks.
 the plausibility of it

It should always possible. Although references to the struct's members would probably be very tricky and require a lot of extra fancy work.

I should have used 'practicality' instead of 'plausibility'. So maybe not so practical (unless the concept is a real boon). (No, I don't know what a "boon" is either ;) ).
 and the cost (in execution time) of doing so.

Depends completely on the cpu, of course. In general though, it's quite a bit slower (a single fetch or store turns into at least two fetches/stores plus some bitmasking and shifting, maybe uses up extra registers, and would make less of the code fit in cache). But that's the price you pay for using packed structs like that on such a CPU. Or you could just use align(4) to guarantee 32-bit alignment on all fields for all cpus.

Yes, surely that is the way to go. Or... craft structs to align nicely in the first place and make the decision on which CPUs you want one set of code to run on: struct ABC { byte a; byte pad1; byte pad2; byte pad3; int b; // may be improperly aligned on some platforms int64 c; // same issue }

If data offset is really that important, you should use a bitfield.

?
Oct 22 2009
parent reply BCS <none anon.com> writes:
Hello aJ,

 If data offset is really that important, you should use a bitfield.
 


Skip that, D dosn't have bitfields
Oct 22 2009
parent KennyTM~ <kennytm gmail.com> writes:
On Oct 23, 09 01:43, BCS wrote:
 Hello aJ,

 If data offset is really that important, you should use a bitfield.


Skip that, D dosn't have bitfields

http://www.digitalmars.com/d/2.0/phobos/std_bitmanip.html ?
Oct 22 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
AJ wrote:
 How do you make ABC below work on a platform that requires 32-bit integers 
 to be aligned on 32-bit boundaries while keeping the layount and size of ABC 
 the same as on a platform that has no such alignment requirement?
 
 struct ABC
 {
     byte a;
     int b; // may be improperly aligned on some platforms
     int64 c; // same issue
 };

You don't require the layout or size of ABC to be the same on all platforms. C doesn't require it, why should D?
Oct 22 2009
next sibling parent "AJ" <aj nospam.net> writes:
Walter Bright wrote:
 AJ wrote:
 How do you make ABC below work on a platform that requires 32-bit
 integers to be aligned on 32-bit boundaries while keeping the
 layount and size of ABC the same as on a platform that has no such
 alignment requirement? struct ABC
 {
     byte a;
     int b; // may be improperly aligned on some platforms
     int64 c; // same issue
 };

You don't require the layout or size of ABC to be the same on all platforms. C doesn't require it, why should D?

One can dream, can't I?! :)
Oct 22 2009
prev sibling parent "AJ" <aj nospam.net> writes:
Walter Bright wrote:
 AJ wrote:
 How do you make ABC below work on a platform that requires 32-bit
 integers to be aligned on 32-bit boundaries while keeping the
 layount and size of ABC the same as on a platform that has no such
 alignment requirement? struct ABC
 {
     byte a;
     int b; // may be improperly aligned on some platforms
     int64 c; // same issue
 };

You don't require the layout or size of ABC to be the same on all platforms. C doesn't require it, why should D?

I know I was asking for the impossible, I just second-guess myself about some things (especially at the hardware level).
Oct 22 2009