簡體   English   中英

將void指針傳遞給接受非void指針的函數是否安全?

[英]Is it safe to pass a void pointer to function that accepts a non-void pointer?

很簡單,以下代碼是安全/可移植的嗎?

#include <stdio.h>
#include <stdlib.h>

int add(int *a, int *b)
{
  return *a + *b;
}

int main()
{
  int x = 2;
  int y = 3;

  void *ptr1 = &x;
  void *ptr2 = &y;

  fprintf(stdout, "%d + %d = %d\n", x, y, add(ptr1, ptr2));

  return EXIT_SUCCESS;
}

我用-Wall -Werror-Wextra編譯了這個並沒有收到任何警告; 它似乎運行良好。

這是安全的:

C99

指向void的指針可以轉換為指向任何不完整或對象類型的指針。 指向任何不完整或對象類型的指針可能會轉換為指向void的指針並再次返回; 結果應該等於原始指針。

但是你需要確保你的原始指針類型是正確的。

有兩件事需要考慮:

  1. C允許從void指針到任何其他對象指針類型的隱式轉換。 因此,傳遞這些參數在語法上是可以的。

  2. 指向的實際對象的類型以及函數所需的指針類型必須滿足嚴格的別名約束,否則您的程序處於未定義的行為域。

兩點都沒關系。 所以你的程序非常好。

這很好但是你的牙齒皮膚。

您正在將int*轉換為void*並且當指針通過值傳遞給add ,它將轉換回int*

例如,如果add兩個指針來double ,那么代碼的行為將是未定義的。

它是“安全的”,因為行為定義明確。 當一個函數被聲明為接受void *時,它需要處理許多不同類型的數據是正常的; 例如memcpy

這在道德上並不安全。 通過傳遞void *您使編譯器無法檢查您傳遞的指針是否指向包含您期望的形式和數量的數據的內存。 然后由您來強制執行此操作。

在你瑣碎的例子中,你可以看到對象實際上是int ,一切都很好。

但是,一般情況下,在我們將void *傳遞給函數的情況下,我們還應該傳遞額外的信息來描述我們正在移交的內存,其中詳細說明函數可以完成其工作; 如果我們有一個只能處理一種類型的函數,那么我們會對設計決策進行長期而艱苦的研究,這些決策使我們傳遞的是void *值而不是那種類型。

為了理智(並且,取決於編譯器,性能),請考慮將您未編寫的參數標記為const

如果你知道你轉換為void *的指針總是屬於一組已知的類型(例如char,short,int等),你可以創建一個由一個聯合和一個判別式組成的結構類型,並傳遞給它相反,必要時重新鑄造。

您可以將其作為指向未定義類型的指針傳遞,只是為了比void *更具體,並且以這種方式承擔一些責任。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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