Some sort of hack?

Can I check wether my operation system is 32/64 using the code below:


1
2
3
4
5
6
7
8
9
10
11
switch(sizeof(int*))
{
case 8:
    std::cout << "64-bit system" << std::endl;
    break;
case 4:
    std::cout << "32-bit system" << std::endl;
    break;
default:
    std::cout << "What!" << std::endl;
}
Do you want a compile time check or a run-time check?

For a run-time check then yes - assuming that your target system has 8 byte and 4 byte pointers.
@seeplus wrote:
Do you want a compile time check or a run-time check?
I thought my code is compile-time check, how can it be a run-time check?
You can also do this using cstdint. Possibly something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdint>

#if INTPTR_MAX == INT32_MAX
    #define THIS_IS_32_BIT_ENVIRONMENT
#elif INTPTR_MAX == INT64_MAX
    #define THIS_IS_64_BIT_ENVIRONMENT
#else
    #error "Environment not 32 or 64-bit."
#endif

...
#ifdef THIS_IS_64_BIT ENVIRONMENT
    std::cout << "64-bit system\n";
#else
    std::cout << "32-bit system\n";
#endif 

I thought my code is compile-time check, how can it be a run-time check?


That code is executed at run-time - not compile time. My code above is compile-time check - as only 1 of the lines 13 or 15 will be compiled.

This is fine if the code is being executed on the machine/compiler options compiled for, but if the exe code is to be used on different environments then you do need a run-time check. In which case consider:

1
2
3
4
5
6
7
8
#include <cstdint>
...
if (INTPTR_MAX == INT32_MAX)
    std::cout << "32-bit system\n";
else if (INTPTR_MAX == INT64_MAX)
    std::cout << "64-bit system\n";
else
    std::cout "What!\n";

I liked both you replies @seeplus

That code is executed at run-time - not compile time
, thank you for correcting my mistake. I happened to know only two situation when things done at run-time are:

1: Allocating dynamically an array like:
int *ary = new int[5];

2: When a user is involved like:
1
2
int nbr;
cin >> nbr;


You taught me a third situation, But I am wondering what made it be in run-time, is it the sizeof operator?
Last edited on
About this portion of code:
1
2
3
4
5
#ifdef THIS_IS_64_BIT ENVIRONMENT
    std::cout << "64-bit system\n";
#else
    std::cout << "32-bit system\n";
#endif  


Should I write it inside a function? I never seen a directive for the preprocessor written inside a function rather that in the global namespace.
Last edited on
Can I check wether my operation system is 32/64 using the code below

You're checking the size of a pointer. Note that you can run 32-bit applications on 64-bit Windows so it doesn't necessarily tell you about the OS.

I am wondering what made it be in run-time, is it the sizeof operator?

sizeof() will be evaluated at compile time but the switch statement would be executed at runtime.

I never seen a directive for the preprocessor written inside a function rather that in the global namespace.

You can write preprocessor directives anywhere. The preprocessor doesn't care about the rules of the C++ language. It just expands to text and when the preprocessor phase is over the normal C++ compilation starts.

The printing with std::cout will still happen at runtime and need to be inside a function as always. No magic there.

This can be useful to avoid compiling code unnecessarily that will never be used on the target platform, or that cannot even be compiled for whatever reason (imagine you had some 64-bit code that can't be compiled on a 32-bit system without causing compilation errors). One disadvantage with not always compiling all the code is that you need to recompile for different platforms to make sure there are no syntax errors.
Last edited on
You're checking the size of a pointer. Note that you can run 32-bit applications on 64-bit Windows so it doesn't necessarily tell you about the OS.


I am quoting from Marc Gregoir's book Professional c++(recommended by fellow member here)

1
2
const char* text2 = "abcdef";
size_t s3 = sizeof(text2);  // is platform-dependent 


Here, s3 will be 4 when compiled in 32-bit mode, and 8 when compiled in 64-bit mode because it is
returning the size of a const char*, which is a pointer


So I thought this can be a hack to know witch system you have whether 32/64.
Last edited on
Note that you can use if constexpr instead of #if... See:
1
2
3
4
5
6
if constexpr (INTPTR_MAX == INT32_MAX)
    std::cout << "32-bit system\n";
else if constexpr (INTPTR_MAX == INT64_MAX)
    std::cout << "64-bit system\n";
else
    std::cout << "What!\n";
> Can I check wether my operation system is 32/64 using the code below:
https://isocpp.org/wiki/faq/intrinsic-types#sizeof-char

Whilst sizeof(char) by definition is always 1, it's is only required that a char has at LEAST 8 bits.

On some machines (notably DSP chips), a char can have 16 or 32 bits.
But it's size is always 1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <climits>

// https://en.cppreference.com/w/cpp/language/types#Data_models
enum class data_model_t { LP32, ILP32, LLP64, LP64, UNCOMMON } ;

consteval data_model_t current_data_model()
{
    if constexpr( CHAR_BIT != 8 ) return data_model_t::UNCOMMON ; // byte is not an octet

    constexpr std::size_t SZ_INT = sizeof(int) ;
    constexpr std::size_t SZ_LONG = sizeof(long) ;
    constexpr std::size_t SZ_PTR = sizeof(void*) ;

    if constexpr( SZ_INT == 2 && SZ_LONG == 4 && SZ_PTR == 4 ) return data_model_t::LP32 ; // 2/4/4

    else if constexpr( SZ_INT != 4 ) return data_model_t::UNCOMMON ;

    else if constexpr ( SZ_LONG == 4 && SZ_PTR == 4 ) return data_model_t::ILP32 ; // 4/4/4

    else if constexpr ( SZ_LONG == 4 && SZ_PTR == 8 ) return data_model_t::LLP64 ; // 4/4/8

    else if constexpr ( SZ_LONG == 8 && SZ_PTR == 8 ) return data_model_t::LP64 ; // 4/8/8

    else return data_model_t::UNCOMMON ;
}

int main() // usage:
{
    constexpr auto data_model = current_data_model() ;
    static_assert( data_model == data_model_t::LP64 ) ; // eg. 64-bit unix or unix-like
    // static_assert( data_model == data_model_t::LLP64 ) ; // eg. win64 (64-bit windows)
}
I am not sure any of these are ensured. If you install and use a 32 bit compiler, the resulting executable may tell you the OS is 32 bit, using code tricks to try to guess at it, and it may even do that if you build a 32 bit compiler on a 64 bit compiler. I don't know for sure what happens in all these cases, but you should just ask the OS. It will flat out tell you, though you need a library call to ask it, its much safer. (actually, you can get it without a library call if you are willing to ask it via a system call type thing and parse the output).
The data model does not depend only on the OS. For example, on 64-bit Windows, the data models of 64 bit programs are different for the microsoft compiler (LLP64) and the GNU compiler (LP64). For programming information, we need to seek the information from the compiler being used.
A 32-bit compiler/IDE can compile code that runs as 64-bit. Visual Studio 2019 and earlier versions, for example. Visual Studio 2022 requires a 64-bit CPU, though it can create 32-bit executables.

AFAIK there is no cross-platform method for determining if the OS a app is running on is 32-bit/64-bit. There are ways for specifically Windows.

One is to check for the existence of a "Program Files (x86)" folder at the root of your boot drive, along with a "Program Files" folder.

Under the Windows folder there can be other folders if the OS is 64-bit: "SysWOW64" is one.

It is possible to determine if an app is running as 32-bit in a 64-bit Windows environment:

https://www.programmerall.com/article/1349770022/

Doing a 'net search might be useful. Here's a meta-search I used:

https://duckduckgo.com/?q=c%2B%2B+determine+if+OS+is+32-bit+or+64-bit&t=ffsb&ia=web
Can I check wether my operation system is 32/64 using the code below

That code determines at run-time if you compile the code as 32- or 64-bit. That doesn't determine the bit-ness of the OS that runs the app.

How you determine the bit-ness when an app is running is likely going to require using OS-specific system calls, Windows kinda makes it easier by having special system folders if it is 64-bit that don't exist with 32-bit.
There are lots of web-pages with "simple code" on the internet that allegedly show how to determine what the bit-ness of an OS is with a running app, they are crap with a capital 'C'. The code determines the bit-ness the app was compiled as.

For example: https://iq.opengenus.org/detect-operating-system-in-c/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
#ifdef _WIN32 // Includes both 32 bit and 64 bit
#ifdef _WIN64
   printf("Windows 64 bit\n");
#else
   printf("Windows 32 bit\n");
#endif
#else
   printf("Not a Windows OS\n");
#endif
   return 0;
}

Looks kinda straight-forward, doesn't it. But it doesn't work as intended.

Using Visual Studio 2022 compiled and run as x64:
Windows 64 bit

Compiled and run as x86 (32-bit):
Windows 32 bit

Same OS, just compiled differently.

Run the two apps on a Win x86 system and the 32-bit app will run. The x64 app will not execute at all.

I can't remember what the Win error message states off the top of my head.
Topic archived. No new replies allowed.