Mason Watmough
Mason Watmough

Reputation: 495

How to make sure a data type is as large as it needs to be in C++

Is there a simple way to make sure data types remain the same size across different platforms and architectures in C/C++?

In C++, let's say I have written a hypothetical, bare-bones program:

#include <iostream>

int foo;

int main(void)
{
    std::cout<<"Size of foo is "<<sizeof(foo)<<" bytes."<<std::endl;
    return 0;
}

All this program does is print the size of an arbitrary integer data type and exit. On my machine, it returns the size of foo as 4 bytes (I have a 64-bit machine).

But, let's say I write this program for an Arduino or other ATMega powered board:

int foo;
void setup()
{
    Serial.begin(9600);
    Serial.print("Size of foo is ");
    Serial.print(sizeof(foo));
    Serial.println(" bytes.");
}
void loop(){}

On my Arduino UNO board, this only returns 2 (same size as short on my machine).

Is it possible to make a (prefereably cross-platform) header or declaration to make sure that the size of a data type is a certain size, so as not to run into precision problems or issues with very large numbers?

Ideally, this would work with not just Arduino boards, but also other compact MCUs (like the PicKit).

I'm relatively new to Arduino and the whole Arduino IDE in general, so forgive me if I'm missing something super simple.

Upvotes: 3

Views: 125

Answers (2)

Emil Laine
Emil Laine

Reputation: 42828

Yes. Use a fixed width integer type defined in <cstdint>, usually one of the following:

int8_t
int16_t
int32_t
int64_t
uint8_t
uint16_t
uint32_t
uint64_t

There are also other ones for different use cases. They are available since C++11.

Upvotes: 4

Mats Petersson
Mats Petersson

Reputation: 129314

A reasonably modern C++ implementation should have the header <cstdint>, which provides intN_t and uintN_t, where N is 8, 16, 32 and 64. Using those well defined types will guarantee that either the code will compile and behave as you wish, or not compile, so you won't get the problems with "my code isn't doing what I expect from a 32-bit integer". For super-portability, you could use `int_

In a system that doesn't have <cstdint>, you could achieve the same thing with some suitable typedef based on for example what compiler (e.g. #if defined(__GCC__) && define(__i386__) ... or some make-file trickery of sampling the size of various expected types and then generating the right typedef lines.

Upvotes: 5

Related Questions