Reputation: 31
We have two kinds of remote systems in our university; we can connect to them remotely and work. I wrote a C program on one of the systems where size of void pointer and size of size_t variable is 8 bytes. But when I connected to other system, my program started working differently. I wasted too much time debugging for the reason and finally found that it is happening due to architecture differences between the two systems.
My questions are:
On what factors the size of primitive types depend?
How to know the size of primitive types before we start programming?
How to write cross platform code in C?
Upvotes: 0
Views: 2532
Reputation: 205
I ask this question of every developer I hire.
My quess is you are doing this.
struct A {
int X; // 2 or 4 or 8 bytes
short Y; // 2 bytes
}
On 32 bit computer you get a structure that is 48 bits, 32 for int, 16 for the short.
On the 64 bit computer you get structure that is 80 bits long, 64 for in, 16 for short.
(Yes, I know, all kinds of esoteric stuff might happen here, but the goal is solve the problem, not to confuse the questioner.)
The problem comes about when you tried to use this struct to read what was written by the other.
You need a structure that will marshall correctly.
struct A {
long X; // 4 bytes
short Y; // 2 bytes
}
Now both sides will read and write the data correctly in most cases, unless you have monkeyed with the flags.
If you are sending stuff across the wire you must use the char, short, long, etc. If you are not then you can use int, as int and let the compiler figure it out.
Upvotes: 0
Reputation: 7918
Question:
On what factors the size of primitive types depend & How to know the size of primitive types before we start programming?
The CPU and the compiler.
To understand Primitive types one has to understand types of Primitive types, there are two types of Primitive types:
The integer data types range in size from at least 8 bits to at least 32 bits. The C99 standard extends this range to include integer sizes of at least 64 bits. The sizes and ranges listed for these types are minimums; depending on your computer platform, these sizes and ranges may be larger.
signed char : 8-bit integer values in the range of −128 to 127.
unsigned char : 8-bit integer values in the range of 0 to 255.
char : Depending on your system, the char data type is defined as having the same range as either the signed char or the unsigned char data type
short int : 16-bit integer values in the range of −32,768 to 32,767
unsigned short int : 16-bit integer values in the range of 0 to 65,535
int : 32-bit integer values in the range of −2,147,483,648 to 2,147,483,647
long int : 32-bit integer range of at least −2,147,483,648 to 2,147,483,647 (Depending on your system, this data type might be 64-bit)
unsigned long int : 32-bit integer range of at least −2,147,483,648 to 2,147,483,647 (Depending on your system, this data type might be 64-bit)
long long int : 64-bit Integer values in the range of −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. (This type is not part of C89, but is both part of C99 and a GNU C extension. )
unsigned long long int: 64-bit integer values in the range of at least 0 to 18,446,744,073,709,551,615 (This type is not part of C89, but is both part of C99 and a GNU C extension. )
float : float data type is the smallest of the three floating point types, if they differ in size at all. Its minimum value is stored in the FLT_MIN, and should be no greater than 1e-37. Its maximum value is stored in FLT_MAX, and should be no less than 1e37.
double : The double data type is at least as large as the float type. Its minimum value is stored in DBL_MIN, and its maximum value is stored in DBL_MAX.
long double : type is at least as large as the float type, and it may be larger. Its minimum value is stored in DBL_MIN, and its maximum value is stored in DBL_MAX. Question:
How to write cross platform code in C?
Cross Platform code has two things to do that are:
Upvotes: 1
Reputation: 3486
Jonathan Leffler basically covered this in his comments, but you technically cannot know how large primitive types will be across systems/architectures. If a system follows the C standard, then you know you will have a minimum number of bytes for every variable type, but you may be given more than that value.
For example, if I am writing a program that uses a signed long
, I can reliably know that I will be given at least 4 bytes and that I can store numbers up to 2,147,483,647; however, some systems could give me more than 4 bytes.
Unfortunately, a developer cannot know ahead of time (without testing) how many bytes a system will return, and thus good code should be dynamic enough to account for this.
The exceptions to this rule are int8_t
, int16_t
, int32_t
, int64_t
and their unsigned counterparts (uintn_t
). With these variable types you are guaranteed exactly n number of bits - no more, no less.
Upvotes: 0
Reputation: 137418
How to write cross platform code in C?
If you need to marshal data in a platform-independent way (e.g. on a filesystem, or over a network), you should be consistent in (at least) these things:
Datatype sizes - Rely on the types from <stdint.h>
. For example, if you need a two-byte unsigned integer, use uint16_t
.
Datatype alignment/padding - Be aware of how members in a struct
are packed/padded. The default alignment of a member may change from one system to another, which means a member may be at different byte offsets, depending on the compiler. When marshalling data, use __attribute__((packed))
(on GCC), or similar.
Byte order - Multi-byte integers can be stored with their bytes in either order: Little-endian systems store the least-significant byte at the lowest address/offset, while Big-endian systems start with the most-significant. Luckily, everyone has agreed that bytes are sent as big-endian over the network. For this, we use htons
/ntohs
to convert byte order when sending/receiving multi-byte integers over network connections.
Upvotes: 1
Reputation: 2547
In general Size of integer in a processor depends on how many bits ALU can operate in single cycle. For e.g.
i)For 8051 Architecture as size of data bus is 8 bits ,All 8051 compilers specifies size of integer is 8 bits.
ii) For 32 bit ARM architecture as data bus is 8 bits wide size of integer is 32 bits.
You should always refer the compiler documentation for correct size of data types.
Almost all compiles declares their name/version as a predefined macro,you can use them in your header file like this:
#ifedef COMPILER_1
typedef char S8
typedef int S16
typedef long S32
:
:
#else COPILER_2
typedef int S32
typedef long S64
:
:
#endif
Then in you code you can declare variables like
S32 Var1;
Upvotes: 1
Reputation: 206607
Question:
On what factors the size of primitive types depend?
The CPU and the compiler.
Question:
How to know the size of primitive types before we start programming?
You can't. However, you can write a small program to get the sizes of the primitive types.
#include <stdio.h>
int main()
{
printf("Size of short: %zu\n", sizeof(short));
printf("Size of int: %zu\n", sizeof(int));
printf("Size of long: %zu\n", sizeof(long));
printf("Size of long long: %zu\n", sizeof(long long));
printf("Size of size_t: %zu\n", sizeof(size_t));
printf("Size of void*: %zu\n", sizeof(void*));
printf("Size of float: %zu\n", sizeof(float));
printf("Size of double: %zu\n", sizeof(double));
}
Question:
How to write cross platform code in C?
Upvotes: 1