質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • C++

    3764questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

同じ変数名の多重定義を許可したくない

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,078

aglkjggg

score 719

 質問

forループを書くとforの反復として使う変数iだけでなくその他変数名もforループ内で重複して定義できます。
プログラムミス(バグ)が生まれる可能性が高いのでC#のようにエラー(※画像1)を出したいのですがVisual Studioにどのような設定を行えばよいでしょうか。

また、C++はなぜこのような厄介なプログラムのミス(バグ)に繋がりそうな仕様を認めてしまったのでしょうか…


画像1. C#のエラー

 プログラム

int main()
{
  for (int i = 0; i < 10; i++)
  {
    for (int i = 0; i< 10; i++)
    {
      printf("%d", i);
    }
    printf("★%d\n", i);
  }
}

出力結果

Visual Studio 2017(v141)とgcc 5.4.0で同じ出力結果が確認できました。

01234567890
01234567891
01234567892
01234567893
01234567894
01234567895
01234567896
01234567897
01234567898
01234567899
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+7

プロジェクトの構成プロパティ->C/C++->コマンドラインの追加のオプションに/we4456を追加することでC4456警告のみをエラーとして扱えます。

ビルド結果例

1>------ ビルド開始: プロジェクト:CppApp1, 構成:Debug Win32 ------
1>stdafx.cpp
1>CppApp1.cpp
1>~\cppapp1.cpp(11): error C4456: 'i' を宣言すると、以前のローカル宣言が隠蔽されます
1>~\\cppapp1.cpp(9): note: 'i' の宣言を確認してください
1>プロジェクト "CppApp1.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

参考:
Compiler Warnings C4400 Through C4599
/w、/Wn、/WX、/Wall、/wln、/wdn、/wen、/won (警告レベル)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/22 10:52

    ありがとうございます。
    やりたいことが実現できました。

    ※毎回ダイアログから操作するのも面倒なのでメモ。
    // エラーにする
    #pragma warning(error:4456)

    // 警告にする
    #pragma warning(1:4456)

    キャンセル

  • 2017/03/22 10:55

    よかったです。たしかに#pragmaでやったほうが簡単ですね。

    キャンセル

+2

C# でも 6.0 からできるようになりました。

C# 6 の新機能 

ところが、C# 6では、この前半のような判定は、大変な割にメリットが少ないということで、判定しない(エラーにならない)よう変更されました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/22 10:54 編集

    返信ありがとうございます。
    C#はC++に比べるととても厳しい制約がつけられていた時があり、C#6で少し緩和されたのですね…
    今知りました><

    キャンセル

0

以下のようなコードもバグを生みがちなので許すべきではない、と仰ってます?

{
    int i;
    {
        int i;
        ...
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/22 10:45 編集

    はい。
    変数名が同じでブロックが深くなるとわかりづらくなるので、そのように考えておりました。

    しかし、よく考えるとブロック内で同じ名前の変数を定義してもブロック外の同じ名前の変数に影響がないので特に問題が無いかも知れませんね…。

    いい反例が思いつきませんでした><

    私自身最近C#ばかり書いていて、C++が久しぶりだったので言語の違いで違和感を感じてただけかもしれません…

    キャンセル

0

C++はなぜこのような厄介なプログラムのミス(バグ)に繋がりそうな仕様を...

これは誰しも気づいたとき「そっかー」と感じた経験があるのではないかと思います。
ただ本件については若干微妙な問題にも思えます。epistemeさんがおっしゃっているようなコードをあえて書きたくなる場合もあるような。

(もちろんIDEのチェック機構を使って明示的に厳しい方向へ制限するという対処はよいと思います。)

逆にC#でもラムダ記法などで充分小さなスコープが多数出現するようなケースでは、スコープを区別できることが容易であるにもかかわらず「この変数名は使えない」と言われることのほうが使いずらいと感じます。微妙な例ではありますが、以下のようなケースだと自分のコードがよくないのかC#が厳しいのか迷うことがあります。Zuishinさんのコメントを拝見するとこれはC#6だと許されるようになったんですね...

List<int> l1 = ...
List<List<int>> l2 = ...
l1.Select(i => l2[i].Select(i => i+1)...);
                            ^

Scalaなどはlambdaを多用するせいか、ちょっとでもスコープが変われば文句はいわれないようです。一般的に本件の仕様として何がよいのかは、それぞれの言語の記述能力やプログラミングのスタイルなどにも影響されるのではないかと、そんなことを感じました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C++

    3764questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。