如何确定操作系统是否为C中的POSIX?

his*_*amp 22 c gcc posix

相关问题
如何在C/C++中检测操作系统?

如何在GCC或ANSI C中找出我在运行的操作系统?

我会好的如果我能知道我是否在POSIX上运行.


更新:

无论是在编译时还是在运行时,它对我没有任何影响.我在调试例程中使用它,因此性能并不重要.

我正在寻找路径分隔符.Windows和Unix/Linux/BSD会没事的.

而且,我正在尝试在路径上找到基本名称.我找到了一些解决方案,但解决方案包括许多我不想要的包含.我要修改这个解决方案.


我在Mac OS X 10.4.11上,按照这个URL,我执行并得到以下输出:

mac $ touch myfile.c
mac $ gcc -std=c99 -E -dM myfile.c
#define __DBL_MIN_EXP__ (-1021)
#define __FLT_MIN__ 1.17549435e-38F
#define __CHAR_BIT__ 8
#define __WCHAR_MAX__ 2147483647
#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
#define __FLT_EVAL_METHOD__ 0
#define __DBL_MIN_10_EXP__ (-307)
#define __FINITE_MATH_ONLY__ 0
#define __GNUC_PATCHLEVEL__ 1
#define __SHRT_MAX__ 32767
#define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L
#define __APPLE_CC__ 5367
#define __UINTMAX_TYPE__ long long unsigned int
#define __LDBL_MAX_EXP__ 1024
#define __SCHAR_MAX__ 127
#define __USER_LABEL_PREFIX__ _
#define __STDC_HOSTED__ 1
#define __LDBL_HAS_INFINITY__ 1
#define __DBL_DIG__ 15
#define __FLT_EPSILON__ 1.19209290e-7F
#define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L
#define __ppc__ 1
#define __strong 
#define __APPLE__ 1
#define __DECIMAL_DIG__ 33
#define __LDBL_HAS_QUIET_NAN__ 1
#define __DYNAMIC__ 1
#define __GNUC__ 4
#define __DBL_MAX__ 1.7976931348623157e+308
#define __DBL_HAS_INFINITY__ 1
#define __STRICT_ANSI__ 1
#define __weak 
#define __DBL_MAX_EXP__ 1024
#define __LONG_LONG_MAX__ 9223372036854775807LL
#define __GXX_ABI_VERSION 1002
#define __FLT_MIN_EXP__ (-125)
#define __DBL_MIN__ 2.2250738585072014e-308
#define __DBL_HAS_QUIET_NAN__ 1
#define __REGISTER_PREFIX__ 
#define __NO_INLINE__ 1
#define _ARCH_PPC 1
#define __FLT_MANT_DIG__ 24
#define __VERSION__ "4.0.1 (Apple Computer, Inc. build 5367)"
#define __BIG_ENDIAN__ 1
#define __SIZE_TYPE__ long unsigned int
#define __FLT_RADIX__ 2
#define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L
#define __NATURAL_ALIGNMENT__ 1
#define __FLT_HAS_QUIET_NAN__ 1
#define __FLT_MAX_10_EXP__ 38
#define __LONG_MAX__ 2147483647L
#define __FLT_HAS_INFINITY__ 1
#define __STDC_VERSION__ 199901L
#define _BIG_ENDIAN 1
#define __LDBL_MANT_DIG__ 106
#define __WCHAR_TYPE__ int
#define __FLT_DIG__ 6
#define __INT_MAX__ 2147483647
#define __LONG_DOUBLE_128__ 1
#define __FLT_MAX_EXP__ 128
#define __DBL_MANT_DIG__ 53
#define __WINT_TYPE__ int
#define __LDBL_MIN_EXP__ (-968)
#define __MACH__ 1
#define __LDBL_MAX_10_EXP__ 308
#define __DBL_EPSILON__ 2.2204460492503131e-16
#define __INTMAX_MAX__ 9223372036854775807LL
#define __FLT_DENORM_MIN__ 1.40129846e-45F
#define __PIC__ 1
#define __FLT_MAX__ 3.40282347e+38F
#define __FLT_MIN_10_EXP__ (-37)
#define __INTMAX_TYPE__ long long int
#define __GNUC_MINOR__ 0
#define __DBL_MAX_10_EXP__ 308
#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
#define __PTRDIFF_TYPE__ int
#define __LDBL_MIN_10_EXP__ (-291)
#define __LDBL_DIG__ 31
#define __POWERPC__ 1
mac $
Run Code Online (Sandbox Code Playgroud)

Arj*_*kar 31

Single UNIX Specification需要存在unistd.h,它可以告诉你POSIX版本(通过_POSIX_VERSION宏).

但是,unistd.h如果您还不知道自己实际上是在UNIX上进行编译,那么如何包含?

这就是这个海湾合作委员会文件的方便之处.根据它,测试存在或评估到真__unix__应该告诉你系统是UNIX.所以:

#ifdef __unix__
/* Yes it is a UNIX because __unix__ is defined.  */

#include <unistd.h>

/* You can find out the version with _POSIX_VERSION.
..
..  */

#endif
Run Code Online (Sandbox Code Playgroud)

__unix__ 在Mac OS X上没有定义,所以为了解决这个问题,您可以改为:

#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
Run Code Online (Sandbox Code Playgroud)

要获取系统上特定于系统的预定义宏的列表,您可以执行:

cpp -dM /dev/null
Run Code Online (Sandbox Code Playgroud)

例如,我的GNU/Linux系统还另外限定__linux____gnu_linux__分开__unix__和一堆其他的东西.


你必须看到的另一个有用的文件就是这个Wiki.

继续提供一种以类似于我上面描述的方式检测POSIX的存在和版本的方法.


编辑:因为你真的想要做所有这些因为你想决定使用哪个目录分隔符,所以请查看此URL.它说:

注意 Windows API中的文件I/O函数将"/"转换为"\"作为将名称转换为NT样式名称的一部分,除非使用"\?\"前缀,如以下部分所述.

我没有在Windows上编程,或者对它任何了解,所以我不能说我已经对此有所了解.

  • `unistd.h`定义`_POSIX_*`宏.UNIX是POSIX,所以肯定有一个`unistd.h`.我的观点是你可以拥有一个不符合UNIX的POSIX兼容系统,其中不会定义`__unix__`(猜测真的如此).简而言之,POSIX不是UNIX.;-) (7认同)
  • 嗯,你知道UNIX(主要是)POSIX,但并不意味着非UNIX不是POSIX. (4认同)
  • @someguy:请参阅[可以使用C预处理器判断文件是否存在吗?](http://stackoverflow.com/questions/142877/can-the-c-preprocessor-be-used-to-tell-if-一个文件,存在) (2认同)

mch*_*son 5

可以使用autoconf工具解决存在的问题unistd.h,然后#define HAVE_UNISTD_H 1在发现的config.hif中添加一行,从而解决您的问题unistd.h,但是我发现autoconf有点难以使用,并且已经过时了。

如果有机会使用cmake,则可以用相同的方法解决。您可以创建一个config.h.in包含以下内容的内容:

#ifndef CONFIG_H
#define CONFIG_H

#cmakedefine HAVE_UNISTD_H 1

#endif
Run Code Online (Sandbox Code Playgroud)

您的项目CMakeLists.txt如下所示:

project(MyApp)

include(CheckIncludeFiles)
check_include_file("unistd.h" HAVE_UNISTD_H)

configure_file(config.h.in config.h @ONLY)

add_executable(${PROJECT_NAME} main.c)
Run Code Online (Sandbox Code Playgroud)

然后从命令行生成:

cmake . -G"Unix Makefiles"
Run Code Online (Sandbox Code Playgroud)

或生成Xcode项目(仅限OSX):

cmake . -G"Xcode"
Run Code Online (Sandbox Code Playgroud)

或生成Visual Studio 2013解决方案项目(仅限Windows):

cmake . -G"Visual Studio 12 2013 Win64"
Run Code Online (Sandbox Code Playgroud)

cmake生成器=史诗般的胜利

如果您的操作系统是POSIX,则生成的内容config.h应如下所示:

#ifndef CONFIG_H
#define CONFIG_H

#define HAVE_UNISTD_H 1

#endif
Run Code Online (Sandbox Code Playgroud)

否则,它将如下所示:

#ifndef CONFIG_H
#define CONFIG_H

/* #undef HAVE_UNISTD_H */

#endif
Run Code Online (Sandbox Code Playgroud)

然后,您就可以自由使用您信任的生成的config.h

#include "config.h"

#if HAVE_UNISTD_H
#   include <unistd.h>
#endif

int main (int argc, const char * argv[])
{
#if defined(_POSIX_VERSION)
     /* POSIX code here */
#else
     /* non-POSIX code here */
#endif
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Lys*_*aly 5

我知道这是一个死问题,但我必须添加这个。

在 C++17(以及作为GCCclang扩展的 C)中,现在有一个__has_include可以在#if指令中使用的运算符。这意味着您可以像这样检查 posix 合规性:

#if __has_include(<unistd.h>)
    // System is posix-compliant
#else
    // System is not posix-compliant
#endif
Run Code Online (Sandbox Code Playgroud)