19

次の例を使用しgccてコンパイルします-Wall -pedantic

#include <stdio.h>

int main(void)
{
  printf("main: %p\n", main); /* line 5 */
  printf("main: %p\n", (void*) main); /* line 6 */

  return 0;
}

私は得る:

main.c:5: warning: format ‘%p’ expects type ‘void *’, but argument 2 has type ‘int (*)()’
main.c:6: warning: ISO C forbids conversion of function pointer to object pointer type

5行目で、6行目のようにコードを変更しました。

関数のアドレスを出力するときに警告を削除するために何が欠けていますか?

4

4 に答える 4

17

これは基本的に、関数ポインタを出力する唯一の移植可能な方法です。

size_t i;
int (*ptr_to_main)() = main;
for (i=0; i<sizeof ptr_to_main; i++)
    printf("%.2x", ((unsigned char *)&ptr_to_main)[i]);
putchar('\n');
于 2012-06-07T14:03:29.277 に答える
6

一部のシステムはコードとデータに異なるサイズのポインターを使用するため、このアイデア全体は実際には移植性がありません。

本当に必要なのは、関数ポインターの大きさに関するプラットフォーム固有の知識と、そのサイズの整数型へのキャストです。残念ながら、データポインタを保持できるintfuncptr_tアナログを標準化した人はいないと思います。intptr_t


R.が彼の回答signedで述べているように、ポインタはいつでも(おそらくまたはunsigned)の配列として扱うことができますchar。このようにして、正しいサイズの整数型は必要ありません。

于 2012-06-07T13:37:28.963 に答える
5

警告の中にあります。ISOCは、関数ポインタをオブジェクトポインタ型(を含む)に変換することを禁止していますvoid*この質問も参照してください。

関数のアドレスを移植可能な方法で出力することはできないため、警告を取り除くことはできません。

@R..の提案を使用して関数ポインタを出力できます。

于 2012-06-07T13:37:44.987 に答える
4

関数ポインターをvoidポインターに変換することは技術的に危険ですが、関数ポインターをvoidポインターに変換することは、POSIX標準で使用されているため、ほとんどのコンパイラーで機能することはほぼ確実です。

見上げるdlsym()

于 2012-06-07T13:38:27.423 に答える