簡體   English   中英

在C ++,g ++ / clang ++和vc ++中打印函數的地址,誰是對的?

[英]Print an address of function in C++, g++/clang++ vs vc++ , who is right?

考慮以下簡單程序:

#include <iostream>
void foo() { }
int main() {
    std::cout<<static_cast<void*>(foo);
}

它在VC++上可以正常編譯,但是g++clang++會給出編譯錯誤。

在此處觀看實時演示( VC++

在此處觀看現場演示( clang++

在此處觀看實時演示( g++

g++clang++提供的診斷信息:

source_file.cpp: In function ‘int main()’:
source_file.cpp:4:38: error: invalid static_cast from type ‘void()’ to type ‘void*’
     std::cout<<static_cast<void*>(foo);
                                  ^

因此,問題是根據C ++標准,哪個編譯器在這里? 我認為g++clang++行為在這里是正確的。 我知道我應該在這里使用reinterpret_cast而不是static_cast 這是VC++編譯器中的錯誤嗎? 如果答案取決於C ++的特定標准,那么我也很好奇。

GCC和Clang是正確的,因為您嘗試執行的轉換不在static_cast可以執行的轉換之中。 這些轉換在[expr.static.cast]中進行了枚舉。 我將通過參考本節中的段落來簡要總結它們:

  • 基礎到派生參考轉換(p2)
  • 轉換為引用兼容類型(x3)的xvalue
  • 使用操作數進行轉換以進行直接初始化(p4)
  • 轉換為空(p6)
  • 標准轉換順序的倒數(p7)
  • 整數/枚舉轉換(p9,p10)
  • 基礎到派生指針轉換(p11)
  • 派生至基本指針到成員的轉換(p12)
  • 空指針到對象指針的轉換(p13)

此外,p5說:

不得使用static_cast明確執行其他任何轉換。

函數或函數指針到void*的轉換不在列出的轉換中。

特別是,由於沒有從函數指針到void*標准轉換,因此不適用直接初始化。 根據[conv.ptr] / 2:

可以將類型為“ pointer to cv T ”(其中T是對象類型)的prvalue轉換為類型為“ pointer to cv void ”的prvalue。 將對象類型的指針的非空指針值轉換為“ cv void指針”的結果表示內存中與原始指針值相同的字節的地址。 空指針值將轉換為目標類型的空指針值。

請注意,這僅覆蓋對象指針,而不覆蓋函數指針。

這個指向空指針的參考中

指向任何類型對象的指針都可以隱式轉換為void指針

[強調我的]

從此函數參考

函數不是對象

這似乎表明指向函數的指針根本無法轉換為void*

暫無
暫無

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

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