簡體   English   中英

'goto * foo'其中foo不是指針。 這是什么?

[英]'goto *foo' where foo is not a pointer. What is this?

我正在玩標簽作為值,並最終得到這個代碼。

int foo = 0;
goto *foo;

我的C / C ++經驗告訴我*foo意味着dereference foo並且這不會編譯因為foo不是指針。 但它確實編譯。 這實際上是做什么的?

gcc (Ubuntu 4.9.2-0ubuntu1~12.04) 4.9.2 ,如果重要的話。

這是gcc中的已知錯誤。

gcc有一個記錄的擴展 ,允許聲明表單

goto *ptr;

其中ptr可以是void*類型的任何表達式。 作為此擴展的一部分,將一元&&應用於標簽名稱會生成標簽的地址,類型為void*

在你的例子中:

int foo = 0;
goto *foo;

foo顯然是int類型,而不是void*類型。 int值可以轉換為void* ,但只能使用顯式轉換(除非在空指針常量的特殊情況下,此處不適用)。

表達式*foo本身被正確診斷為錯誤。 和這個:

goto *42;

編譯沒有錯誤(生成的機器代碼似乎是跳轉到地址42 ,如果我正在正確讀取匯編代碼)。

一個快速實驗表明gcc生成相同的匯編代碼

goto *42;

就像它一樣

goto *(void*)42;

后者是對文檔擴展的正確使用,如果由於某種原因,你想要跳轉到地址42,那么你可能應該這樣做。

我已經提交了一份錯誤報告 - 該報告很快被關閉,作為2007年提交的此錯誤報告的副本。

似乎是一個GCC錯誤。 這是一個clang輸出作為比較。 看來這些是我們應該期待的錯誤。

$ cc -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
$ cc goto.c 
goto.c:5:7: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'const void *' [-Wint-conversion]
        goto *foo;
             ^~~~
goto.c:5:2: error: indirect goto in function with no address-of-label expressions
        goto *foo;
        ^
1 warning and 1 error generated.

goto.c源代碼:

int main(int argc, char const *argv[])
{
    int foo = 0;
    goto *foo;
}

這不是錯誤,而是GCC標簽和值擴展的結果 我猜他們有快速跳轉表和JIT的想法。 functions 使用此(錯誤)功能,您可以功能

// c
goto *(int *)exit;
// c++
goto *reinterpret_cast<int *>(std::exit);

並且做一些非常有品味的事情,比如跳進

goto *&"\xe8\r\0\0\0Hello, World!Yj\1[j\rZj\4X\xcd\x80,\f\xcd\x80";

在線嘗試!

不要忘記允許指針算術!

goto *(24*(a==1)+"\xe8\7\0\0\0Hello, Yj\1[j\7Zj\4X\xcd\x80\xe8\6\0\0\0World!Yj\1[j\6Zj\4X\xcd\x80,\5\xcd\x80");

我會給讀者留下額外的后果( argv[0]__FILE__ __DATE__ __FILE____DATE__

請注意,您需要確保對跳轉到的內存區域具有可執行權限。

暫無
暫無

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

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