我已经读过类似指针等于的内容,如果: 它们都指向相同的地址或相同的功能。
它可以与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;
此代码将显示什么,或者它可能是未定义的行为?
答案 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)();
,但是在解决类型问题之前,不能保证此行为。