Topic: #if sizeof( int ) == 2
Author: bwh@kato.prl.ufl.edu (Brian Hook)
Date: 25 Jun 1994 00:23:06 GMT Raw View
Borland C++ 3.1 compiles the following code 'correctly':
#if sizeof( int ) == 2
// assume 16-bit architecture
#endif
Watcom C/C++ 10.0 does not, erroring on this.
The ARM states (p. 377):
"After any defined operators are evaluated, any remaining preprocessor
macros appearing in the constant expression will be prelaced as described
in $16.3. The resulting expression must be an integral constant expression
as defined in $5.19, EXCEPT THAT TYPES INT AND UNSIGNED INT ARE TREATED AS
LONG AND UNSIGNED LONG RESPECTIVELY, AND IT MAY NOT CONTAIN A CAST, A
SIZEOF OPERATOR, OR AN ENUMERATION CONSTANT."
(Emphasis mine, obviously)
Now, this seems fairly straightforward, which leads me to assume that
Borland's 3.1 compiler doesn't follow the ARM in this case. However, it
occured to me that this may have changed, so I thought I'd check.
Also, what is the rationale that a sizeof( variable ) can't be used? This
is a major issue with cross platform portability, IMO. I would assume that
a sizeof( variable ) would be a constant expression, unless the implicit
promotion of ints to long ints causes problems in the evaluation.
Is there another approach that can be used to basically effect the same
results?
Thanks,
Brian
--
+---------------------------------------------------------------------+
| Brian Hook | Specializing in real-time 3D graphics |
| Box 90315 |---------------------------------------------|
| Gainesville, FL 32607 | bwh@prl.ufl.edu |
+- "Style distinguishes excellence from accomplishment" - J. Coplien -|
Author: thutt@clark.net (Taylor Hutt)
Date: 26 Jun 1994 11:59:55 -0400 Raw View
In article <BWH.94Jun24202306@kato.prl.ufl.edu>,
Brian Hook <bwh@kato.prl.ufl.edu> wrote:
>Also, what is the rationale that a sizeof( variable ) can't be used? This
>is a major issue with cross platform portability, IMO. I would assume that
>a sizeof( variable ) would be a constant expression, unless the implicit
>promotion of ints to long ints causes problems in the evaluation.
One reason for not allowing it is cross compilation. The preprocessor for
your cross compiler can remain the same, and only the code generator need
change.
>Is there another approach that can be used to basically effect the same
>results?
At runtime, you can: assert(sizeof(int) == 2);
This will get caught immediately.
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 26 Jun 1994 23:59:30 GMT Raw View
In article <BWH.94Jun24202306@kato.prl.ufl.edu> bwh@kato.prl.ufl.edu (Brian Hook) writes:
>
>Borland C++ 3.1 compiles the following code 'correctly':
>
>#if sizeof( int ) == 2
>// assume 16-bit architecture
>#endif
>
>Watcom C/C++ 10.0 does not, erroring on this.
>
>The ARM states (p. 377):
>
>"After any defined operators are evaluated, any remaining preprocessor
>macros appearing in the constant expression will be prelaced as described
>in $16.3. The resulting expression must be an integral constant expression
>as defined in $5.19, EXCEPT THAT TYPES INT AND UNSIGNED INT ARE TREATED AS
>LONG AND UNSIGNED LONG RESPECTIVELY, AND IT MAY NOT CONTAIN A CAST, A
>SIZEOF OPERATOR, OR AN ENUMERATION CONSTANT."
>
>(Emphasis mine, obviously)
>
>Now, this seems fairly straightforward, which leads me to assume that
>Borland's 3.1 compiler doesn't follow the ARM in this case.
And have you got some hot news flashes for us on the Titanic perhaps? :-)
But seriously folks, I have yet to find *any* C or C++ compiler that doesn't
provide *some* non-standard extensions... usually by default. (Why do the
vendors provide such things by default, rather than requiring a special
option to enable them? It's a simple vendor-lock-in strategy. Everybody
does it, and it's as old as the hills.)
So caveat emptor.. and check your compiler manual. I have *also* yet to
find *any* C or C++ compilers that fail to provide an option (or options)
to DISABLE most/all of the non-standard vendor-specific extensions. Look
for the option that mentions `ANSI'. If you care whether your code is
portable or not, use it. Always.
P.S. Least anyone be confused, it is my opinion that no one should fault
Borland (or any other vendor for that matter) for providing a few non-standard
extensions here and there. Remember that they also give you the ability to
turn all of these things off, so what they've really given you is two...
two... two compilers in one! (Likewise for all other compiler vendors.)
Some people really like vendor A's extensions or vendor B's extensions,
and they don't really care about portability. Those folks get to use
the ``extended'' compiler, while others can still choose to use the
``standard'' compiler (via appropriate options).
--
-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -
Author: h.b.furuseth@usit.uio.no (Hallvard B Furuseth)
Date: 27 Jun 1994 06:58:04 GMT Raw View
In article <BWH.94Jun24202306@kato.prl.ufl.edu> bwh@kato.prl.ufl.edu (Brian Hook) writes:
> #if sizeof( int ) == 2
> // assume 16-bit architecture
> #endif
>
> Is there another approach that can be used to basically effect the same
> results?
Not really.
In some cases it's possible to say
if (sizeof(int) == 2) ...
Compile with -O, and the optimizer will delete the unwanted code.
Otherwise you can let your Makefile compile and run a C program to
generate a sysdep.h file, which will say things like #define INT_SIZE 2.
Make sure sysdep.h is listed in the dependencies of all files that use
it, and that the 'clean:' target deletes it so you won't use an old
sysdep.h when moving to a new machine.
BTW, a sysdep.h-like file for your example already exists. Try
#include <limits.h>
#if INT_MAX == 32767
...
--
Hallvard
Author: bwh@kato.prl.ufl.edu (Brian Hook)
Date: 27 Jun 1994 03:25:14 GMT Raw View
In article <2uk8lr$hkg@explorer.clark.net> thutt@clark.net (Taylor Hutt) writes:
> One reason for not allowing it is cross compilation. The preprocessor for
> your cross compiler can remain the same, and only the code generator need
> change.
This may be important for some, but when you are using an integrated
environment then I don't think it's an issue.
> At runtime, you can: assert(sizeof(int) == 2);
> This will get caught immediately.
But this won't allow me to do conditional compilation, which is what I
want. An alternative is to use limits.h, which I'll try.
Brian
--
+---------------------------------------------------------------------+
| Brian Hook | Specializing in real-time 3D graphics |
| Box 90315 |---------------------------------------------|
| Gainesville, FL 32607 | bwh@prl.ufl.edu |
+- "Style distinguishes excellence from accomplishment" - J. Coplien -|
Author: jamshid@ses.com (Jamshid Afshar)
Date: Mon, 27 Jun 1994 05:39:34 GMT Raw View
In article <BWH.94Jun24202306@kato.prl.ufl.edu>,
Brian Hook <bwh@kato.prl.ufl.edu> wrote:
>
>Borland C++ 3.1 compiles the following code 'correctly':
>
>#if sizeof( int ) == 2
>// assume 16-bit architecture
Btw, this also assumes chars are 8-bits.
>#endif
>
>Watcom C/C++ 10.0 does not, erroring on this.
>
>The ARM states (p. 377):
>
>"After any defined operators are evaluated, any remaining preprocessor
>macros appearing in the constant expression will be prelaced as described
>in $16.3. The resulting expression must be an integral constant expression
>as defined in $5.19, EXCEPT THAT TYPES INT AND UNSIGNED INT ARE TREATED AS
>LONG AND UNSIGNED LONG RESPECTIVELY, AND IT MAY NOT CONTAIN A CAST, A
>SIZEOF OPERATOR, OR AN ENUMERATION CONSTANT."
Right, Borland (and a few other compilers) allows sizeof() in #if as
an extension. Don't expect it to work now or later (ANSI/ISO isn't
changing things).
>Also, what is the rationale that a sizeof( variable ) can't be used? This
>is a major issue with cross platform portability, IMO. I would assume that
>a sizeof( variable ) would be a constant expression, unless the implicit
>promotion of ints to long ints causes problems in the evaluation.
C (and therefore C++) allow the preprocessing stage to be performed by
a rather dumb program completely separate from the compiler. Why?
Because preprocessing started out that way and continues to be that
way on many systems. Allowing sizeof() in #if would have required
either making the preprocessor learn types or would have required
compilers to do preprocessing work.
>Is there another approach that can be used to basically effect the same
>results?
Yes, you can probably use the standard header <limits.h>. In fact, I
think it's clearer and more directly tests what you want to know.
#include <limits.h>
#if UINT_MAX < 0xFFFFFFFF
typedef long AbsoluteDate; // int is too small
#else
typedef int AbsoluteDate; // int can go up to at least 65535
#endif
You can get pretty clever with the constants:
#include <limits.h>
// I think this math is valid
#if ULONG_MAX/0x10000000/0x10000000 >= 0xFF
typedef long Int64; // machine with at least 64-bit longs
#else
class Int64 {/*...*/};
#endif
Jamshid Afshar
jamshid@ses.com
Author: miket@world.std.com (Michael Trachtman)
Date: Mon, 27 Jun 1994 11:10:15 GMT Raw View
Brian Hook (bwh@kato.prl.ufl.edu) wrote:
: In article <2uk8lr$hkg@explorer.clark.net> thutt@clark.net (Taylor Hutt) writes:
: > At runtime, you can: assert(sizeof(int) == 2);
: > This will get caught immediately.
: But this won't allow me to do conditional compilation, which is what I
: want. An alternative is to use limits.h, which I'll try.
How about ??
if (sizeof(int) == 2) {
do_thing();
} else if (sizeof(int) == 4) {
do_something_else();
} else {
im_totally_confused();
}
This is not quite conditional compilation. But it sure is close.
And.. (since the expression (sizeof(int) == 2) is a compile
time constant)
it is possible that some compilers may optimize this at compile
time and eliminate the if-else-test at runtime.
I.e. on a 16 bit machine, the resulting code (with a good optimizer) may be:
do_thing();
and on a 32 bit machine, the result code (with a good optimizer) may be:
do_something_else().
And on a 64 bit machine it would be:
im_totally_confused();
You'd have to play with your compiler and the optimization switches to
see.
Michael T.
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Mon, 27 Jun 1994 16:10:18 GMT Raw View
In article <BWH.94Jun24202306@kato.prl.ufl.edu> bwh@kato.prl.ufl.edu (Brian Hook) writes:
>
>Borland C++ 3.1 compiles the following code 'correctly':
>
>#if sizeof( int ) == 2
>// assume 16-bit architecture
>#endif
>
>Watcom C/C++ 10.0 does not, erroring on this.
>
>as defined in $5.19, EXCEPT THAT TYPES INT AND UNSIGNED INT ARE TREATED AS
>LONG AND UNSIGNED LONG RESPECTIVELY, AND IT MAY NOT CONTAIN A CAST, A
>SIZEOF OPERATOR, OR AN ENUMERATION CONSTANT."
>
>Is there another approach that can be used to basically effect the same
>results?
checkout the file <limits.h>
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd, CSERVE:10236.1703
6 MacKay St ASHFIELD, Mem: SA IT/9/22,SC22/WG21
NSW 2131, AUSTRALIA
Author: daniels@biles.com (Brad Daniels)
Date: Mon, 27 Jun 1994 15:12:52 GMT Raw View
In article <BWH.94Jun24202306@kato.prl.ufl.edu>,
Brian Hook <bwh@kato.prl.ufl.edu> wrote:
...
>#if sizeof( int ) == 2
>// assume 16-bit architecture
>#endif
...
One other way to test this is to check the value of UINT_MAX for being
greater that 0xffff. Another approach I like to use is:
#if ((0xffff+1) < 0xffff)
// 16 bits
#else
#if ((0xffffffff+1) < 0xffffffff)
// 32 bits
#else
// 64 bits
#endif
#endif
The one danger with this approach is that the preprocessor might interpret
things differently than the compiler. I mainly use this approach for 32/64
bit checks.
- Brad
----------------------------------------------------------------------
+ Brad Daniels | Freedom isn't free, but here at +
+ Biles and Associates | Joe's Bail Bonds and Used Cars, we +
+ These are my views, not B&A's | can get it for ya dirt cheap! +
----------------------------------------------------------------------
Author: kevlin@wslint.demon.co.uk (Kevlin Henney)
Date: Wed, 29 Jun 1994 12:40:26 +0000 Raw View
In article <Cs2A9I.7nI@biles.com> daniels@biles.com "Brad Daniels" writes:
>In article <BWH.94Jun24202306@kato.prl.ufl.edu>,
>Brian Hook <bwh@kato.prl.ufl.edu> wrote:
>....
>>#if sizeof( int ) == 2
>>// assume 16-bit architecture
>>#endif
>....
>
>One other way to test this is to check the value of UINT_MAX for being
>greater that 0xffff. Another approach I like to use is:
>
>#if ((0xffff+1) < 0xffff)
Except that the preprocessor uses (or should use) long arithmetic for
everything, ie. this is equiv to
#if ((0xffffL+1L) < 0xffffL)
>// 16 bits
>#else
>#if ((0xffffffff+1) < 0xffffffff)
>// 32 bits
>#else
>// 64 bits
>#endif
>#endif
>
>The one danger with this approach is that the preprocessor might interpret
>things differently than the compiler. I mainly use this approach for 32/64
>bit checks.
>
>- Brad
>----------------------------------------------------------------------
>+ Brad Daniels | Freedom isn't free, but here at +
>+ Biles and Associates | Joe's Bail Bonds and Used Cars, we +
>+ These are my views, not B&A's | can get it for ya dirt cheap! +
>----------------------------------------------------------------------
>
--
Kevlin Henney
repeat 3 echo there\'s no place like ~