[英]What is the behaviour of comparing pointer to static variable?
我讀過類似指針等於的內容,如果:它們都指向相同的地址或相同的函數。
它是否與static
功能相同但名稱不同的static
功能一起使用?
main.c :
#include <stdio.h>
extern void *p1;
extern void *p2;
int main() {
printf("%d\n", p1 == p2);
return 0;
}
啊 :
static void f() {}
公元前 :
#include "A.h"
void *p1 = &f;
抄送 :
#include "A.h"
void *p2 = &f;
該代碼將打印什么,或者可能是未定義的行為?
該代碼將具有未定義的行為,但是由於C標准沒有指定將函數的指針轉換為void
的指針會發生的原因。
將指針轉換為函數的可轉換性轉換為指向void
的指針被列為通用擴展名( C11 J.5.7 ),而POSiX則要求這樣做。 但是,它可能仍應使用顯式強制轉換。
兩個指向一個函數的指針只有在指向同一個函數時才會相互比較( C11 6.5.9p6 )
只有當兩個指針都是指向同一對象的指針(包括指向對象及其開頭的子對象的指針)或函數時,兩個指針的比較才相等。
內部翻譯在不同翻譯單元中的兩個函數是不同的,因此指向它們的指針應該比較不相等; 如果可以保證往返,則同樣進行void *
轉換。
我讀過這樣的標准,即如果鏈接器將兩個定義與相同的代碼合並 ,則實現不是一個符合標准的實現。 ( C11 6.2.2p2 )
您的代碼中有2個問題:
如果函數在每個模塊中都是static
定義的,則編譯器將為每個模塊生成一個不同的對象,鏈接器可能會合並也可能不會合並,因為兩個模塊的static
代碼相同,無論它們的static
名稱是否相同。 但是,這種優化似乎不符合要求,因此函數應具有不同的地址。
指針的類型為void *
,不能保證明確地保存函數指針。 實際上,C標准並未定義將函數指針轉換為對象類型指針的行為。 因此,除非您假定擴展了C標准,否則行為是不確定的。 您應該使用類型void (*p1)();
定義p1
void (*p1)();
等等
該程序很可能會輸出0
,但是在解決類型問題之前,不能保證此行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.