#ifdef for 32-bit platform

2019-02-04 06:54发布

In an application I maintain, we've encountered a problem with file descriptor limitations affecting the stdlib. This problem only affects the 32-bit version of the standard lib.

I have devised a fix for my code and would like to implement it, but only when compiling for 32-bit executable. What pre-processor symbol can I #ifdef for to determine whether the code is being compiled for a 32 or 64-bit target?

EDIT

Sorry, didn't mention, the code is cross-platform, linux, windows, solaris and a few other unix flavors, mostly using GCC for compilation. Any de-facto standards I can use cross-platform?

EDIT 2

I've found some definitions "__ILP23" and "__LP64" that seem like they may work... a discussion here explains the background on the unix platform. Anyone had any experience with using these defines? Is this going to be usable?

11条回答
虎瘦雄心在
2楼-- · 2019-02-04 07:05

I would test it indirectly, via the maximum pointer value constant:

#include <stdint.h>

#if UINTPTR_MAX == 0xffFFffFF
// 32-bit platform
#elif UINTPTR_MAX == 0xffFFffFFffFFffFF
// 64-bit platform
#else
#error Unknown platform - does not look either like 32-bit or 64-bit
#endif

This way you don't rely on any platform-specific define for architecture, but on the direct consequence of having a specific architecture - the pointer size.

查看更多
等我变得足够好
3楼-- · 2019-02-04 07:06

What I would probably end up doing, is within a Makefile, determine if you are on a 32 bit platform or 64 bit using uname. Then, add to your CFLAGS, -DX32, or -DX64. That you could just #ifdef X64.

But this is just a unixy solution. I'm not sure what I would do on windows.

查看更多
仙女界的扛把子
4楼-- · 2019-02-04 07:06

At least 32-bit Solaris has a limit of 256 file pointers because the structure stores the file descriptor in an unsigned char field. This is retained for backwards compatibility with some almost impossibly old versions of SunOS. Other platforms - I'm tempted to say most other platforms - do not share that limitation. On the other hand, it is relatively unusual for an ordinary user program to need that many files open concurrently; it more often indicates a bug (not closing the files when finished with them) than not. Having said that, though, it can be a problem for things like database servers which need to have lots of data files open at the same time.


One comment says:

That's almost it. We don't have a large number of files open, but the server handles a large number of connections from clients. Socket handles and file descriptors seem to come from the same place. When we have a lot of connections, 'fopen' fails because the system-level call returns and fd > 255.

'Socket handles' are file descriptors at the system call level, so they come from the same place as regular file descriptors for files.

If you have to work around this, then you need to wrap your current socket opening code so that if it gets an file descriptor in the range 0..255, then it calls 'dup2()' to create a file descriptor in the range that stdio won't use - and then close the original file descriptor. The only snag with this is that you have to keep track of which file descriptors are available, because dup2 will merrily close the target file descriptor if it is currently open.

Of course, I'm assuming your socket code reads file descriptors and not file pointers. If that's the case, you have bigger problems - too many things want to use the same resources and they can't all use them at the same time.

查看更多
混吃等死
5楼-- · 2019-02-04 07:11

I believe the define is _WIN64

查看更多
地球回转人心会变
6楼-- · 2019-02-04 07:19

I'm not sure if there is a universal #if def that is appropriate. The C++ standard almost certainly does not define one. There are certainly platform spcefic ones though.

For example, Windows

#if _WIN64 
// 64 bit build
#else
// 32 bit build
#endif

EDIT OP mentioned this is a cross compile between Windows and Non-Windows using GCC and other compilers

There is no universal macro that can be used for all platforms and compilers. A little bit of preprocessor magic though can do the trick. Assuming you're only working on x86 and amd64 chips the following should do the trick. It can easily be expanded for other platforms though

#if _WIN64 || __amd64__
#define PORTABLE_64_BIT
#else
#define PORTABLE_32_BIT
#endif
查看更多
SAY GOODBYE
7楼-- · 2019-02-04 07:20

Depends on your OS and compiler, those are implementation decisions.

查看更多
登录 后发表回答