【问题标题】:Check for definition GNU C检查定义 GNU C
【发布时间】:2012-06-20 23:59:47
【问题描述】:

我正在尝试更多地了解预处理器是如何与 GNU/Linux 上的 GCC 生成的共享对象库相关的。

我一直无法找到一个清晰、简洁的答案。

如果我使用如下预处理器语句:

#ifndef __OPTI_MY_VARIABLE
#define __OPTI_MY_VARIABLE 1
#endif

我用这个编译一个共享对象文件,并用另一个我声明的程序链接到它:

#define __OPTI_MY_VARIABLE 2

在编译使用共享对象库的主程序后,我的程序会使用值 1 还是 2?

如果它使用值 1,有没有办法构造代码使其使用值 2,例如不使用预处理器语句?换句话说,我有没有办法声明默认值,除非另一个同名的全局变量覆盖它,或者必须将此信息传递给共享对象中的函数?

【问题讨论】:

  • 来自7.1.3 保留标识符:“所有以下划线和大写字母或另一个下划线开头的标识符始终保留供任何使用。”
  • 在我运行 gcc 4.6.1 的 64 位 Debian 不稳定版上,我收到了重新定义宏的警告,但最终它的值为 2。通过阅读代码,宏似乎将采用始终值为 2。没有什么可以阻止您自己这样做。这是问题还是我错过了什么?
  • 我一直在做一些测试,如果我一次编译整个东西,它的值是 2,但是如果我创建一个动态或静态库并编译它,然后在我的其他代码,它的值是1。令人困惑......但我找到了一种方法。我在第一次包含标头时定义了全局变量。

标签: c linux gcc c-preprocessor shared


【解决方案1】:

#defines 只有预处理器才能看到。预处理器在编译器之前完全运行。编译器在链接之前运行。

如果您希望能够覆盖共享对象“内部”的默认值,那么我建议您使用 setter 函数和静态全局变量,例如:

#define OPTI_MY_VARIABLE_DEFAULT   1

static int opti_my_variable = OPTI_MY_VARIABLE_DEFAULT;

...

void set_opti_my_variable(int i) { opti_my_variable = i; }

显然,这使用了一个全局变量,许多人对此不以为然...

【讨论】:

  • 谢谢。这回答了第一个问题。但是,它并没有回答我能做什么。我可以做点什么吗?
【解决方案2】:

问题是错误的。

那些定义意味着在源代码中所有出现的定义名称都被给定的值替换,在编译之前

因此,在一个共享库中,无论您在哪里使用该名称,您的值都是 1。在另一个共享库中,值是 2。共享库中不存在该名称。如果您将两个共享库与一个程序一起使用,那么第一个库中设置定义名称的任何变量都将具有值 1,而在第二个库中,值将是 2。

【讨论】:

    猜你喜欢
    • 2023-03-09
    • 2013-09-13
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多