比较指针与静态变量的行为是什么?

时间:2019-04-07 14:20:15

标签: c pointers static comparison

我已经读过类似指针等于的内容,如果: 它们都指向相同的地址或相同的功能。

它可以与static函数一起使用吗?这些函数同名但具有不同的地址?

main.c

#include <stdio.h>

extern void *p1;
extern void *p2;

int main() {
    printf("%d\n", p1 == p2);
    return 0;
}

A.h

static void f() {}

公元前

#include "A.h"
void *p1 = &f;

抄送

#include "A.h"
void *p2 = &f;

此代码将显示什么,或者它可能是未定义的行为?

2 个答案:

答案 0 :(得分:3)

该代码将具有未定义的行为,但是由于C标准没有指定将指向功能的指针转换为指向{{1}的指针时将发生的情况, }

将指针对函数的可转换性转换为对void的指针被列为公共扩展名(C11 J.5.7),POSiX要求这样做。但是,它可能仍应使用显式强制转换。


指向函数的两个指针只有在指向同一函数(C11 6.5.9p6)时才会相互比较

  

当且仅当[...]时,两个指针比较相等,两者都是指向同一对象的指针(包括指向对象和其子对象开头的指针)或函数,[...]

在不同翻译单元中具有内部链接的两个函数是不同的,因此指向它们的指针应该比较不相等;以及void的转换(如果可以保证往返)。


我这样阅读标准,即如果链接器使用相同的代码合并这两个定义,则该实现不是符合标准的。 (C11 6.2.2p2

答案 1 :(得分:0)

您的代码中有2个问题:

  • 该函数在每个模块中定义static,编译器将为每个模块生成一个不同的对象,链接器可能会合并也可能不会合并,因为两者的代码相同,无论它们是否相同{ {1}}名称。但是,这种优化似乎不符合要求,因此函数应该具有不同的地址。

  • 指针的类型为static,不能保证明确地保存函数指针。实际上,C标准并未定义将函数指针转换为对象类型指针的行为。因此,除非您假定扩展了C标准,否则行为是不确定的。您应该使用类型void *等定义p1

该程序很可能会输出void (*p1)();,但是在解决类型问题之前,不能保证此行为。