gcc -D_REENTRANT到底做了什么?

时间:2015-08-20 14:07:41

标签: c gcc java-native-interface

我正在为C库编写Java绑定,因此正在使用JNI。合理地,Oracle specifies应该使用多线程感知编译器编译用于Java的本机库。

JNI文档提供了一个具体示例:对于gcc,应通过定义宏_REENTRANT_POSIX_C_SOURCE中的一个来满足此多线程感知要求。这对我来说似乎很奇怪。 _REENTRANT_POSIX_C_SOURCE是功能测试宏。 GCC和POSIX文档描述了它们在定义符号和使声明可见方面的效果,正如我对任何特征测试宏所期望的那样。

如果我不需要额外的符号或功能,那么这些宏实际上对我有用吗?是否有一个或两个导致gcc生成不同于其他代码的代码?它们是否可能导致我的代码对标准库函数的调用链接到不同的实现?或者甲骨文是在谈论它的下层区域?

编辑: 此外,我发现重入是线程的一个单独考虑因素。即使对于单线程程序,非重入也可能是一个问题,因此Oracle建议定义_REENTRANT使gcc多线程感知现在看起来更加可疑。

1 个答案:

答案 0 :(得分:2)

Oracle建议是针对Solaris编写的,而不是针对Linux编写的。

在Solaris上,如果您编译了.so而没有_REENTRANT并最终被多线程应用程序加载,那么可能会发生非常糟糕的事情(例如libc内部的随机数据损坏)。这是因为没有定义,默认情况下你会得到一些例程的未锁定变体。

当我第一次阅读这篇文档时就是这种情况,这可能是15年前,在我上次阅读本文档之后添加了对sun studio编译器的-mt标志的提及。

现在不再是这种情况了 - 无论你是否使用_REENTRANT标志进行编译,现在总是得到相同的例程;它现在只是一个功能宏,而不是行为宏。