🔒 Locked
Variable size...
Advertisement
Original Post
I want to declare variables of exact sizes...
An int is always the size of a single register on the CPU you compile on. But I want to declare a signed integer that will always be 32 bits in size. How do I that? How do I do the same to create a 16-bit unsigned integer?
I once saw something like this...
int myVar:24;
... which was supposed to create a 24-bit signed integer. But I''ve yet to come across a compiler that doesn''t call syntax errors on that.
Please help me out?
VC++.NET(and 6.0, I assume) accept extensions like __int32, __int16 and __int64. Other compilers will have equivalent extensions. I suggest you wrap this with a typedef and an #if/#endif block.
The syntax you suggest comes from bitfields. For instance:
struct Flags
{
unsigned int is_keyword:1;
unsigned int is_extern:1;
unsigned int is_static:1;
};
This creates three variables of 1-bit each.
But bitfields are very implementation dependant and generally no assumptions can be made. For isntance, it is not known whether the bits above are packed or aligned on 1, 2, 4 or 8 byte bounderies.
Only integers can be declared as bitfields.
In general I would go for the solution used by most APIs. Create a header that contains #defines that check the current compiler and then defines new types to match the same sizes you want.
#ifdef _win32
#define INT32 int
#define INT16 short
#endif
and so on for other systems also.
struct Flags
{
unsigned int is_keyword:1;
unsigned int is_extern:1;
unsigned int is_static:1;
};
This creates three variables of 1-bit each.
But bitfields are very implementation dependant and generally no assumptions can be made. For isntance, it is not known whether the bits above are packed or aligned on 1, 2, 4 or 8 byte bounderies.
Only integers can be declared as bitfields.
In general I would go for the solution used by most APIs. Create a header that contains #defines that check the current compiler and then defines new types to match the same sizes you want.
#ifdef _win32
#define INT32 int
#define INT16 short
#endif
and so on for other systems also.
quote:
Original post by Peaceman
why did you forget the easiest solution?
short = 16 bit integer
long = 32 bit integer
double= 64 bit integer
Did I missunderstand the question or what?
Double is a floating point value not an integer, but it is true that it is a 64-bit floating point value.
I guess you don''t know C. Those sizes are correct on a Intel 32-bit PC. They are not true in general - and no sizes are given in the C and C++ standard.
For instance on the Digital Alpha 64-but arhitecture the following is the case:
short = 16 bit
int = 32-bit
long = 64-bit
or on a 80286 processor (if I recall correctly):
short = 16 bit
int = 16 bit
long = 16 bit
quote:
I guess you don''t know C. Those sizes are correct on a Intel 32-bit PC. They are not true in general - and no sizes are given in the C and C++ standard.
Yeah, you''re right about me not knowing C. I started with C++ so I didn''t actually quite see the problem :-D
Thanks for explaining it to me anyway.
Continuing Wyrframe''s question - is it possible to create custom sized variables (I don''t think anyone''s actually found an answer to it in this thread)? Let''s suppose I do want to create a 24-bit integer type variable with the very same properties as a regular integer? felonius, is there a way to make sure that my new-sized variable will behave correctly if I use it, for instance, in: fread(ptr, sizefo(myVar), n, stream)??
Does anyone know how the built in variables in C/C++ are defined?
Crispy
Does anyone know how the built in variables in C/C++ are defined?
Crispy
quote:
Original post by Crispy
Continuing Wyrframe's question - is it possible to create custom sized variables (I don't think anyone's actually found an answer to it in this thread)? Let's suppose I do want to create a 24-bit integer type variable with the very same properties as a regular integer? felonius, is there a way to make sure that my new-sized variable will behave correctly if I use it, for instance, in: fread(ptr, sizefo(myVar), n, stream) ??
You can't create actual new basic types. The closest you get is by using bit-fields as part of a struct but as said there is no garantee that they are packed and it will probably include passing so if we have
struct myType
{
myVar:24;
};
then sizeof(myType) will likely be 4 or 8 depending on the compiler - not 3 as you might want.
and it certainly will not work with fread.
quote:
Does anyone know how the built in variables in C/C++ are defined?
The built-in types are built-in so they cannot be defined in the language itself, if that is what you mean. The only requirement in the C standard concerning size is that
sizeof(short) <= sizeof(int)
sizeof(int) <= sizeof(long)
sizeof(float) <= sizeof(double)
sizeof(double) <= sizeof(long double)
You cannot say anything about sizeof(char). You cannot assume it is 1.
[edited by - felonius on June 16, 2002 12:34:58 PM]
[edited by - felonius on June 16, 2002 12:35:36 PM]
quote:
Original post by tsuraan
Doesn't the C spec say that sizeof(char) returns 1? Or is that out of date?
I don't own the official standard document (ISO sells it from their website - maybe I should buy one) but in the Reference Manual in the back of Kernighan & Ritchie: The C Programming Language in section A4.2 it says:
"Objects declared as characters (char) are large enough to store any member of the execution character set. If a genuine character from the set is stored in a char object, its value is equivalent to the integer code for the character, and is non-negative. Other quantities may be stored into char variables, but the available range of values, and especially whether the value is signed, is implementation-dependent."
So the size of char and even whether it is signed or unsigned by default is compiler dependent. In practice, however, so many programs assume that sizeof(char)=1 that nobody would dare make a compiler that did not do this.
quote:
Original post by jaxson
You are correct. sizeof() always returns 1 for type char.
So no, it doesn't. On all the machines I know it does, but this is not garanteed.
[edited by - felonius on June 16, 2002 2:08:57 PM]
VC++, at least, allows you to specify how structures should be packed in the compiler options, and in the compiler command line(you can use a pragma too).
Shouldn''t it be possible to force a 4 byte pack like this:
struct __int24
{
int theInt:24;
__int8 unused;
}
?
____________________________________________________________
Direct3D vs. OpenGL
Shouldn''t it be possible to force a 4 byte pack like this:
struct __int24
{
int theInt:24;
__int8 unused;
}
?
____________________________________________________________
Direct3D vs. OpenGL
quote:
Original post by Promit
VC++, at least, allows you to specify how structures should be packed in the compiler options, and in the compiler command line(you can use a pragma too).
Shouldn''t it be possible to force a 4 byte pack like this:
struct __int24
{
int theInt:24;
__int8 unused;
}
?
Possibly, you could try it out. But be aware that you are then completely MVC++ specific.
You could write like this:
#pragma pack(1)
struct __int24
{
int theInt:24;
__int8 unused;
}
#pragma pack()
It might work but it is completely compiler dependent and it will not work on other systems.
The value of sizeof(char) is ALWAYS one, since sizeof returns the size of the data type measured in characters. The sizeof operator does not return the number of bytes of the data type. I''ll find the reference to this (again) in the C99 Draft if I have to
.


Which standard states the minimum sizes for the types? From my reading, I've been lead to believe that in C, sizeof returns the number of bytes a type occupies, but in C++ sizeof returns the number of chars a type occupies. So in C++, sizeof(char) always returns 1, but in C sizeof(char) may return 2 if you have two byte char values.
ex:
char is 2 bytes; C sizeof(char) == 2; C++ sizeof(char) == 1
short is 2 bytes; C sizeof(short) == 2; C++ sizeof(short) == 1
int is 4 bytes; C sizeof(int) == 4; C++ sizeof(int) == 2
double is 8 bytes; C sizeof(double) == 8; C++ sizeof(int) == 4
CM
[edit] It sounds like Null and Void is pretty positive sizeof in C works the same way it does in C++, so that half of what I just said should probably be disregarded. I wasn't completely certain about that part anyhow.[/edit]
[edited by - Conner McCloud on June 16, 2002 5:56:44 PM]
ex:
char is 2 bytes; C sizeof(char) == 2; C++ sizeof(char) == 1
short is 2 bytes; C sizeof(short) == 2; C++ sizeof(short) == 1
int is 4 bytes; C sizeof(int) == 4; C++ sizeof(int) == 2
double is 8 bytes; C sizeof(double) == 8; C++ sizeof(int) == 4
CM
[edit] It sounds like Null and Void is pretty positive sizeof in C works the same way it does in C++, so that half of what I just said should probably be disregarded. I wasn't completely certain about that part anyhow.[/edit]
[edited by - Conner McCloud on June 16, 2002 5:56:44 PM]
WG14/N869 Committee Draft -- January 18, 1999 81
6.5.3.4 The sizeof operator
...
Semantics
...
When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.
...
6.5.3.4 The sizeof operator
...
Semantics
...
When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.
...
quote:
Original post by Null and Void
WG14/N869 Committee Draft -- January 18, 1999 81
6.5.3.4 The sizeof operator
...
Semantics
...
When applied to an operand that has type char , unsigned char , or signed char , (or a qualified version thereof) the result is 1.
...
Ups.
Okay, I found this in the final version of the C++ Standard in section 5.3.3 and it states the same thing. And in the C Standard 6.5.3.4 (as mentioned above). So I give in sizeof(char) is always 1 - in both C and C++. We learn something every day.
[edited by - felonius on June 16, 2002 6:14:44 PM]
quote:
Original post by Conner McCloud
Which standard states the minimum sizes for the types? From my reading, I''ve been lead to believe that in C, sizeof returns the number of bytes a type occupies, but in C++ sizeof returns the number of chars a type occupies. So in C++, sizeof(char) always returns 1, but in C sizeof(char) may return 2 if you have two byte char values.
ex:
char is 2 bytes; C sizeof(char) == 2; C++ sizeof(char) == 1
short is 2 bytes; C sizeof(short) == 2; C++ sizeof(short) == 1
int is 4 bytes; C sizeof(int) == 4; C++ sizeof(int) == 2
double is 8 bytes; C sizeof(double) == 8; C++ sizeof(int) == 4
CM
[edit] It sounds like Null and Void is pretty positive sizeof in C works the same way it does in C++, so that half of what I just said should probably be disregarded. I wasn''t completely certain about that part anyhow.[/edit]
Well, since we have now cleared up that a char is both 1 byte large in both C and C++ that difference doesn''t really matter any more.
#include <limits.h>
template<unsigned int I> struct IDENTIFY {};
#ifdef you_do_not_want_your_compiler_to_report_an_error_if_the_size_couldnt_be_determined
template<> struct IDENTIFY<0>
{
typedef void TYPE;
enum {SUPPORTED=0};
};
#endif
template<> struct IDENTIFY<1> { typedef signed char TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<2> { typedef signed short TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<3> { typedef signed long TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<4> { typedef signed long long TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<5> { typedef signed int TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<6> { typedef unsigned char TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<7> { typedef unsigned short TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<8> { typedef unsigned long TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<9> { typedef unsigned long long TYPE; enum {SUPPORTED=1}; };
template<> struct IDENTIFY<10> { typedef unsigned int TYPE; enum {SUPPORTED=1}; };
template<unsigned int N,bool B> struct SIZETYPE {};
#define DECLARE_SIZETYPE_SIGNED(s,b) \
template<> struct SIZETYPE<s,b>
{
enum
{
I = sizeof( signed char ) * CHAR_BIT == s ? 1 :
sizeof( signed short ) * CHAR_BIT == s ? 2 :
sizeof( signed long ) * CHAR_BIT == s ? 3 :
sizeof( signed long long ) * CHAR_BIT == s ? 4 :
sizeof( signed int ) * CHAR_BIT == s ? 5 :
0
};
typedef IDENTIFY<I>::TYPE TYPE;
enum {SUPPORTED=IDENTIFY<I>::SUPPORTED};
};
#define DECLARE_SIZETYPE_UNSIGNED(s,b) \
template<> struct SIZETYPE<s,b>
{
enum
{
I = sizeof( unsigned char ) * CHAR_BIT == s ? 6
sizeof( unsigned short ) * CHAR_BIT == s ? 7
sizeof( unsigned long ) * CHAR_BIT == s ? 8
sizeof( unsigned long long ) * CHAR_BIT == s ? 9
sizeof( unsigned int ) * CHAR_BIT == s ? 10
0
};
typedef IDENTIFY<I>::TYPE TYPE;
enum {SUPPORTED=IDENTIFY<I>::SUPPORTED};
};
DECLARE_SIZETYPE_SIGNED ( 8, true )
DECLARE_SIZETYPE_UNSIGNED ( 8, false )
DECLARE_SIZETYPE_SIGNED ( 16, true )
DECLARE_SIZETYPE_UNSIGNED ( 16, false )
DECLARE_SIZETYPE_SIGNED ( 32, true )
DECLARE_SIZETYPE_UNSIGNED ( 32, false )
DECLARE_SIZETYPE_SIGNED ( 64, true )
DECLARE_SIZETYPE_UNSIGNED ( 64, false )
typedef SIZETYPE< 8, true >::TYPE I8;
typedef SIZETYPE< 8, false >::TYPE U8;
typedef SIZETYPE< 16, true >::TYPE I16;
typedef SIZETYPE< 16, false >::TYPE U16;
typedef SIZETYPE< 32, true >::TYPE I32;
typedef SIZETYPE< 32, false >::TYPE U32;
typedef SIZETYPE< 64, true >::TYPE I64;
typedef SIZETYPE< 64, false >::TYPE U64;
enum { I8_SUPPORT = SIZETYPE< 8, true >::SUPPORTED };
enum { U8_SUPPORT = SIZETYPE< 8, false >::SUPPORTED };
enum { I16_SUPPORT = SIZETYPE< 16, true >::SUPPORTED };
enum { U16_SUPPORT = SIZETYPE< 16, false >::SUPPORTED };
enum { I32_SUPPORT = SIZETYPE< 32, true >::SUPPORTED };
enum { U32_SUPPORT = SIZETYPE< 32, false >::SUPPORTED };
enum { I64_SUPPORT = SIZETYPE< 64, true >::SUPPORTED };
enum { U64_SUPPORT = SIZETYPE< 64, false >::SUPPORTED };
void main()
{
if (I8_SUPPORT)
{
I8 heureka = 10;
}
}
[edited by - mcfly on June 16, 2002 6:24:59 PM]
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement