0

次のコードは私を夢中にさせ、実行するとセグメンテーション違反を引き起こします。ここではファーストクラスのラベルを使用していることに注意してください。

#include <stdio.h>

main()
{
   static void* array[] = {&&label2, &&label1};
   void* programCount = array;

   goto *programCount++;


   label2: ;
     int b = 100;
     printf("%d\n", b);

   label1: ;
     int b2 = 1000;
     printf("%d\n", b2);
}

なぜこれが起こっているのかわかりません、それはうまくコンパイルされます...

4

2 に答える 2

3

この質問は、gcc拡張機能であるLabelsasValuesについて言及しています

質問のコードは正常にコンパイルされますが、を使用してコンパイルすると多くの警告が表示され-Wall -pedanticます。問題はvoid*ポインタへの割り当てにあると思います。次のコードはうまく機能します:

static void* array[] = {&&label2,&&label1};

goto *array[0];

@ouahが書いているように、voidポインタのタイプが間違っています。を使用している場合void**、以下も機能します。

void** programCount = array;

goto *programCount[0];
// or goto *programCount[1];

そして最後に、質問のコードを反映するために、次を使用することもできます

void** programCount = array;

goto **(++programCount);

配列の2番目のラベルにジャンプします(label1)。ポインタの値を評価する前に、事前インクリメントを使用してポインタをインクリメントする必要があることに注意してください。

免責事項:私はラベルを使用したりgoto、CまたはC++で使用したりすることに賛成していません。@jweyrichが関数へのポインタの配列を書いたように、そのような問題に対してより適切な解決策を提供する他の言語要素があります。これは移植性がないため、実際のアプリケーションでは使用しないでください(私がコードレビュー担当者だった場合、レビューを通過しません;-))

于 2013-01-13T19:57:05.737 に答える
1

のタイプがprogramCount 正しくありません。次を使用してvoid **ください。

void **programCount = array;

programCount 次に、次のように2回逆参照する必要があります。

goto *programCount[0];

ラベルにジャンプするにはlabel2、または

goto *programCount[1];

ラベルにジャンプしlabel1ます。

ここで、 &&演算子はGNUCラベルアドレス演算子です。

于 2013-01-13T19:58:42.690 に答える