2010-08-09 8 views
8

많은 언어에서 변수를 선언하고 초기화하기 전에 변수를 사용할 수 있습니다.변수가 초기화되지 않은 상태로 유지되는 이점은 무엇입니까?

int x; 
cout << x; 

이 물론 결과 (당신이 당신의 프로그램이 메모리를 매핑 한 방법을 알고 잘하지 않는 한) 예측할 수없는 반환하지만 내 질문 :

예를 들어, C++, 당신은 같은 조각을 쓸 수 있습니다 컴파일러가이 동작을 허용하는 이유는 무엇입니까?

초기화되지 않은 메모리를 사용하도록 허용 한 결과로 인한 효율성 또는 효율성이 있습니까?

편집 : 사용자에게 초기화를 맡기는 것이 제한된 수명 (쓰기주기)이있는 메모리 매체에 대한 쓰기를 최소화한다는 것이 나에게 발생했습니다. 앞에서 언급 한 '성과'라는 제목 아래에있는 구체적인 예입니다. 감사.

답변

1

경우에 따라 변수를 사용하기 전에 함수에서 돌아온 경우와 같이 필요할 때까지 메모리를 초기화하지 않은 상태로 두는 것이 더 빠릅니다. 어쨌든 나는 모든 것을 초기화한다. 나는 실제 성능이 실제와 다르다는 것을 의심한다. 컴파일러는 쓸모없는 초기화를 최적화하는 고유 한 방법을 갖게 될 것이라고 확신합니다.

4

프로그래밍에서 가장 오래된 변명 : 성능이 향상됩니다!

편집 : 의견을 읽고 동의합니다. 몇 년 전에 성능에 초점을 맞춘 것은 CPU주기 수에 달려있었습니다. 내 첫 번째 C 컴파일러는 전통적인 C (ANSI C 이전의 컴파일러)였으며 모든 종류의 가증 한 컴파일을 허용했습니다. 이러한 현대 성과는 고객의 불만 건수에 관한 것입니다. 새로운 졸업생들에게 우리는 '프로그램이 얼마나 빨리 잘못된 대답을하는지 상관하지 않습니다. 최신 컴파일러 및 개발 도구를 모두 사용하고 버그를 적게 둡니다. 모든 사람이 정시에 집에 갈 수 있습니다.

+2

선언하지 않음으로써 성능이 향상되지 않습니까? 그런 식으로 메모리를 변수에 할당 할 필요조차 없습니다. 이 유형의 코드에 대해 성능을 인용하는 사람은 누구나 명백히 잘못입니다. –

+1

키워드는 * 가장 오래된 *. 40 년 전 C가 개발 될 때 변수를 자동으로 초기화하는 명령 또는 두 가지를 "낭비"한다는 것이 실제로 중요했을 것입니다. – dan04

+0

지시 낭비는 가치가있을 수 있지만 성능면에서 추가 지시 (또는 2 ~ 3 개)를 사용하면 응용 프로그램 성능이 떨어집니다. –

1

일부 언어에는 일부 변수 유형에 대한 기본값이 있습니다. 즉, 언어를 명시 적으로 초기화하지 않으면 성능상의 이점이있는 것으로 생각됩니다. 그러나 단점은 다음과 같습니다

  • 당신이 충돌을
  • 예상치 못한 값을 위험을 수행하지 않고 초기화해야한다는 가능성 다른 프로그래머

나의 제안에 대한 명확성과 목적

  • 부족 항상 변수를 초기화하고 일관성은 자체적으로 지불하게됩니다.

  • 4

    의이 전달 변수를 통해 데이터를 반환하도록 설계되어 일부 API, 예컨대 :

    bool ok; 
    int x = convert_to_int(some_string, &ok); 
    

    그것은 그래서 낭비 초기화 함수 내에서 '확인'의 값을 설정할 수 있습니다.

    +1

    이것을 "실제"사용하려면 Qt의 QString 클래스 인 http://doc.qt.nokia.com/4.6/qstring.html#toInt를 참조하십시오. bool * ok를 확인하십시오. – sivabudh

    +0

    은 OUT 유형인지 INOUT 유형인지 여부에 따라 함수 매개 변수에 따라 다릅니다. – YeenFei

    +1

    표준 입력 스트림과 동일 :'bool ok; std :: cin >> ok; ' – rafak

    13

    생각 (나는. API의이 스타일을 옹호하고 있지 않다) (난 그냥 내 아내에게 잘못 전에 봤는데)는 언어 이전의 화신에서 취한 조치는 단순히하다는 있습니다 .

    초기 버전의 C는 함수에서 원하는 곳 어디에서나 변수를 선언 할 수 있도록 허용하지 않았으므로 맨 위에 있어야합니다 (또는 블록 시작 부분에 있어야 할 수도 있습니다. 나는 거의 그렇게하지 않는다.)

    또한 변수가 무엇인지 알아야만 변수를 설정할 수 있습니다. 변수를 초기화 할 때 다음 일은 단순히 그 값을 덮어 쓰는 것입니다 (즉, 성능 사람들이 여기에서 오는 것입니다). 당신은 여전히 ​​당신이 그들을 초기화해야하지 사용 그들 앞에 비록이 하는 것이 필요 왜

    초기화되지 않은 변수를 허용하고, 좋은 컴파일러는 당신이 그것에 대해 알려주는 경고가 있습니다.

    함수에서 변수를 어디에서나 만들 수있는 C++ (및 이후 C 버전)에서는 실제로 변수를 만들고 동시에 초기화해야합니다. 그러나 초기에는 불가능했습니다. 당신은 같은 것을 사용했다 : 내가 선택하는 것, 요즘

    int fn(void) { 
        int x, y; 
        /* Do some stuff to set y */ 
        x = y + 2; 
        /* Do some more stuff */ 
    } 
    

    을위한 :

    int fn(void) { 
        int y; 
        /* Do some stuff to set y */ 
        int x = y + 2; 
        /* Do some more stuff */ 
    } 
    
    +0

    +1 수년간 C/C++이되었다. 이 줄을 따라 답장을 타이핑 했더니, 저를 때려 눕 혔습니다 : 가능한 한 그것을 사용하는 주 코드 논리에 가까운 의미있는 값으로 변수를 초기화하는 것이 현명합니다 - 거리 메트릭. –

    +0

    @ozmo, 이것이 허용 된 대답이어야합니다. – sivabudh

    +1

    +1 현대 컴파일러는 경고 메시지를 표시합니다. 경고 수준을 최고 수준으로 유지 한 다음 모든 경고 오류를 만들고 사용자가 사용하기 전에 사람들을 초기화하는 것과 동일한 효과를냅니다. 인간이 게으르다는 이유만으로 스마트 컴파일러로 보상 할 수있는 것은 아닙니다 .-- 긴 라이브 또는 컴파일러 군주. –

    2

    짧은 대답 더 복잡한 경우에, 컴파일러는 변수 여부를 결정하지 못할 수 있다는 것입니다 초기화 전에 사용되는지 여부.

    예 :

    int x; 
    if (external_function() == 2) { 
        x = 42; 
    } else if (another_function() == 3) { 
        x = 49; 
    } 
    yet_another_function(&x); 
    cout << x; // Is this a use-before-definition? 
    

    좋은 컴파일러는이 가능한 사용하기 전에 초기화 오류를 발견 할 수있는 경우 경고 메시지를 제공하지만, 복잡한 경우에 대한 것 - 특히 여러 컴파일 단위를 포함하는 - 컴파일러가 알 수있는 방법이 없습니다.

    언어가 초기화되지 않은 변수의 개념을 허용하는지 여부는 다른 문제입니다. C#은 모든 변수가 기본값으로 초기화되는 것으로 정의 할 때 약간 특이합니다. 대부분의 언어 (C++/C/BCPL/FORTRAN/Assembler/...)는 초기화가 적절한 지 여부를 프로그래머에게 맡깁니다. 좋은 컴파일러는 때때로 불필요한 초기화를 발견하고 제거 할 수 있습니다. 그러나 이것은 주어지지 않았습니다. 좀 더 모호한 하드웨어 용 컴파일러는 최적화에 투입되는 노력이 적으며 (컴파일러 작성의 어려운 부분 임) 이러한 하드웨어를 대상으로하는 언어는 불필요한 코드 생성을 필요로하지 않습니다.

    0

    변수의 크기에 따라 성능 이름에 값을 초기화하지 않은 상태로 유지하는 것이 미세 최적화로 간주 될 수 있습니다. 상대적으로 소수의 프로그램 (여러 종류의 소프트웨어 유형과 비교할 때)은 두 배를로드하는 데 필요한 2-3 사이클이 추가로 부정적으로 영향을받습니다. 그러나 변수가 꽤 크다는 가정하에 초기 초기화가 지연 될 때까지 초기화가 필요합니다.

    0
    루프 스타일의

    int i; 
    for(i=0;i<something;++i){ 
        ....... 
    } 
    do something with i 
    

    에 대한

    당신은 for 루프가 for(init;condition;inc)

    여기에 절대적으로 필요 하나처럼 보이는 것을 선호

    bool b; 
    do{ 
        .... 
        b = g(); 
        .... 
    }while(!b); 
    
    긴 중첩 된 이름을 가진

    수평 화면 공간

    더 긴 수명의 디버깅 용 범위 지정 g 가시성

    매우 가끔 성능

    관련 문제