2015-11-13 9 views
5

このコードが "期待どおり"に動作しないことがわかりました。ただ、このコードですぐに見て、我々は、戻り値は1であるべきだと思うが、実行には3コンパイラエラーを生成しないスイッチで不正な複数のケース

// incorrect 
variable = 1; 
switch (variable) 
{ 
    case 1, 2: 
    return 1; 
    case 3, 4: 
    return 2; 
    default: 
    return 3; 
} 

リターンを返し、これを行うには、いくつかの適切なオプションがあります

// correct 1 
variable = 1; 
switch (variable) 
{ 
    case 1: case 2: 
    return 1; 
    case 3: case 4: 
    return 2; 
    default: 
    return 3; 
} 

かこれは部分的に私がMultiple Cases in Switch:

になり答えている

// correct 2 
switch (variable) 
{ 
    case 1: 
    case 2: 
    return 1; 
    case 3: 
    case 4: 
    return 2; 
    default: 
    return 3; 
} 

(少なくともBorland C++コンパイラでは)間違ったフォームがエラーや警告なしにコンパイルされる理由を知りたいのです。

コンパイラはこのコードで何を理解していますか?

+3

の価値を持っているという事実にcase 2:に等しい[コンマ演算子のしくみを教えてください](のhttp://のstackoverflow。 com/questions/54142/how-does-the-comma-operator-work) –

答えて

8

はちょうどこのコードですぐに見て、我々は戻り値は1、

されるべきだと思う私は経験豊富なC++開発者はすぐに何かが間違っていることに気づくとすぐに他のいくつかのことを結論だろうと言うと思いますプログラマが誤ってコンマ演算子を使用してみました:,

をが、実行には3

リターンを返します。

ない場合の式は定数

ではないので、コードは、をコンパイルしてはならず、実際のところ、それは、任意の途中現代のコンパイラでコンパイルしません。例えば、MSVC 2013言う:

stackoverflow.cpp(8) : error C2051: case expression not constant 
stackoverflow.cpp(10) : error C2051: case expression not constant 

1, 2等式はコンマ演算子のアプリケーションであり、コンマ演算子は、式がコンパイル時定数ではないことを意味します。

少なくとも11 C++までは、括弧を追加即ちcase (1, 2):は、コンパイルさせられる効果に沿ってrelaxed the rules来ました。あなたが期待しているようなことはしません。

これは一部のスイッチで複数のケースに答えている:

どのように?他の質問とその答えは、C++についてではなく、C++に関するものです。

不適切なフォームがエラー または(少なくともBorland C++コンパイラでは)イベント警告なしでコンパイルされる理由を知りたいと思います。

コンパイラが古すぎるためです。新しいものを手に入れよう。 CまたはC++で

+1

誰かがBorlandにバグレポートを発行する必要があります。 – Walter

+0

@Walter:なぜボランティアはしませんか? :) –

3

私の推測では、最初のケースでは、コンパイラは次のように実行されるコードをもたらすのにコンマ演算子を評価することである:

switch(variable) 
{ 
    case 2: 
    return 1; 
    case 4: 
    return 2; 
    default: 
    return 3; 
} 

上記から、値3を入力するために返される理由それは見ることができ1.コンマ演算子について読んでみることをお勧めします。それに関連するSOにはいくつかの優れたスレッドがあります。

+0

私が投稿したときにあなたの答えを見られませんでした。私たちの答えは事実上同じなので、私はupvoteに義務づけられています:) –

+0

@MadPhysicist:ジェスチャーに感謝します。パブリックフォーラムに参加している丁寧な人たちは、まれにしか珍しくありません。私はあなたが私のようにupvoteに値するので、私は感情を返す。 :) – therainmaker

+0

なぜダウン投票の人々ですか? – therainmaker

1

いくつかの実験を行います。ボーランドC++ 5.5.1 Win32用でコンパイル

#include <stdio.h> 

int test(int variable) { 
    switch (variable) 
    { 
    case 1, 2: 
     return 1; 
    case 3, 4: 
     return 2; 
    default: 
     return 3; 
    } 
} 

int main(void) { 
    int i; 

    for (i = 1; i <= 5; i++) 
    { 
    printf("%d -> %d\n", i, test(i)); 
    } 
    return 0; 
} 

、出力

1 -> 3 
2 -> 1 
3 -> 3 
4 -> 2 
5 -> 3 

た。これは1, 223, 4として解釈されることを示している4として解釈されます。

+0

テストハーネスを書かずにコードを読むだけですぐにわかるでしょうか? –

3

a, bは、CとC++の両方で有効な式です。それは「aを評価し、破棄し、bを評価する」という意味です。式の値はbです。

variable = 1; 
switch(variable) 
{ 
    case 2: 
    return 1; 
    case 4: 
    return 2; 
    default: 
    return 3; 
} 

コンマ演算子の詳細については、あなたがWikipedia articleを読むことができます:だからあなたの元switchは、次のような意味を持っています。

2

a, bという形式の式の値は、bです。それがカンマ演算子の仕組みです。

表面上、case 1, 2:case 2:と等しくなります。

しかし、ケースのラベルが一定一体式である必要があり、それはカンマ演算子が含まれているので1, 2ない定数式である(C++文法は、定数式はコンマ演算子を含むことができないことを指示します)。したがって、コンパイラはエラーを発行する必要があります。

あなたは両方の1と2例のために実行するために、その行を次のステートメントを許可するswitchフォロースルー行動に起因する、case 1: case 2:を頻繁に表示されます。

0

、コンマ式は規則を次のようしている。

  1. は左から右に操作します。
  2. カンマ式​​の値は、最後の式の値です。

だからコードcase 1,2:が原因コンマ式はあなたがチェックしたい場合があります2.

+0

私は本当に多くの人が答える前にコードをコンパイルしようとしないことに本当に驚いています。 –