LoginSignup
7
7

More than 5 years have passed since last update.

using namespace stdに起因する誤作動をJava/C#でも

Posted at

C++でusing namespace stdを使うと、衝突せずにコンパイルが通ってしまう場合があることを知った。
http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice#1453605

例えばこんなコード。

conflict.cpp
#include <algorithm>
#include <cstdio>
//このmin関数はあってもなくてもコンパイルは通るが実行結果は全く異なる
int min(int a,int b){return a+b;}
using namespace std;

int main(){
    printf("%d\n",min(2,3));
    return 0;
}

衝突する場合しか知らなかったのですが、これは怖いですね…。
で、同じようなことをJava/C#でやってみたらできてしまったのでコードを紹介。

conflict.java
import java.util.*;
//このRandomクラスはあってもなくてもコンパイルは通るが実行結果は全く異なる
class Random{
    public int nextInt(){return 123456789;}
}
class Main{
    public static void main(String[]args){
        System.out.println((new Random()).nextInt());
    }
}
  • 異なるパッケージをワイルドカードでインポートしてクラスが衝突したら完全修飾名しか許容しない
  • パッケージ名.クラス名でインポートすることは1度しかできず、そのクラスは必ずクラス名のみで使える
    • 上の例のRandomクラスはこれに相当
conflict.cs
using System;
//このRandomクラスはあってもなくてもコンパイルは通るが実行結果は全く異なる
class Random{
    public int Next(){return 123456789;}
}
class Conflict{
    static void Main(){
        Console.WriteLine((new Random()).Next());
    }
}
  • 異なる名前空間をインポートしてクラスが衝突したら完全修飾名しか許容しない
  • usingディレクティブで(長い)名前空間に別名をつけることは可能

C++も今の状況になったら例えば::minかstd::minしか許容しなくなるようなオプション付けばよいですね。実行前に気づけるので。
…だったら必ずstd::使えばよいのか。using namespace stdして一部の例外だけstd::使うのは気持ち悪いということにもなるし。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7