簡體   English   中英

比較指針與靜態變量的行為是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM