문제

이 코드는 나쁜 관행으로 취급되어야한다고 생각하는 것을 보여 주며 변수를 재정의하거나 마스킹하는 것에 대한 컴파일러의 경고를 이끌어냅니다.

#include <iostream>

int *a;

int* f()
{
  int *a = new int;
  return a;
}

int main()
{
  std::cout << a << std::endl << f() << std::endl;
  return 0;
}

출력 (G ++로 컴파일) :

0
0x602010

나는 몇 가지 참고 문헌 (Stroustrup 및 Complete C ++ 참조)을 보았고 이것이 언제, 왜 허용되는지에 대해 아무것도 찾을 수 없습니다. 그래도 단일 로컬 범위 내에 있지 않다는 것을 알고 있습니다.

언제 그리고 왜 이것이 허용됩니까? 이 구조에 잘 사용됩니까? G ++를 어떻게 경고 할 수 있습니까? 다른 컴파일러가 그것에 대해 squawk합니까?

도움이 되었습니까?

해결책

글로벌 식별자를 안전하게 무시할 수 있도록 허용됩니다. 본질적으로, 당신은 실제로 사용하는 글로벌 이름에 대해서만 관심이 있어야합니다.

당신의 예에서 f() 먼저 정의되었습니다. 그런 다음 다른 개발자가 글로벌 선언을 추가했습니다. 이름을 추가하여 f() 작동했던 상태에서 여전히 작동합니다. 재정의가 오류라면, 새로 추가 된 글로벌 변수와 전혀 아무것도하지 않더라도 기능이 갑자기 작동을 중단합니다.

다른 팁

이것이 허용되는 이유에 관해서 : 이것은 완벽하게 유효합니다.

F () 함수 내에 있으면 로컬 범위를 정의하고 있습니다. 로컬 스코프는 글로벌 범위를 무시하므로 "A"변수 "를 정의하면 글로벌을 숨 깁니다. int *a;

이것은 완벽하게 유효하지만 -Wall 당신은 매개 변수를 섀도우 할 때만 경고를받습니다.

그림자를 할 때 경고를 원한다면 어느 변수의 유형, 당신은 이것을 g++ 수동 페이지 :

   -Wshadow
       Warn whenever a local variable shadows another local variable, 
       parameter or global variable or whenever a built-in function is 
       shadowed.

주목하십시오 -Wshadow 포함되지 않습니다 -Wall 기본적으로.

많은 언어가 이런 종류의 언어를 허용합니다.
일반적으로 (모든 언어와 관련하여) 가장 로컬로 정의 된 변수는 당신이 참조하는 변수입니다. 내가 사용한 20 개 이상의 언어 중에서 매우 일반적입니다.

또한 대부분의 언어를 사용하면 외부 범위의 언어를 명시 적으로 참조 할 수 있습니다.
예를 들어 C ++는 :: Operator와 함께 글로벌 범위의 변수를 지정하도록 alles 다.

#include  <iostream>


int a = 5;
int main()
{
    int a = 6;

    std::cout << a << "\n" << ::a << "\n";
            // Local
                           // global
}

이것이 허용 될 때 대답하기 위해 : 기본적으로 두 개의 중첩 된 스코프.

예를 들어:

void foo() {
    int a;
    {
        int a;
    }
}

class Base {
    int a;
};
class Derived: public Base {
    int a; // Yes, the name Base::a is visible in the scope of Derived, even if private
};

class Foo() {
    int a;
    Foo(int a) : a(a) { } // Works OK
};

using std::swap;
void swap(MyClass& lhs, MyClass& rhs);
// Not strictly a variable, but name lookup in C++ happens before determining 
// what the name means.

이제 대답은 동일한 범위에 단일 이름을 가진 두 개의 '사물'을 갖는 것이 일반적으로 허용된다는 것입니다. 이름 중 하나는 실제로는 가능합니다. 한정된 그 범위에서; 다른 사람들은 단순히 일 것입니다 보이는 그 범위에서. 이름 해상도 규칙은 여러 후보자가있는 경우 선택한 이름을 결정합니다.

컴파일러가 대안 사이를 선택하는 모든 경우에 경고를주고 싶지 않습니다. 그것은 당신에게 과부하와 같은 무고한 것들과 일부 스마트 템플릿 코드에 대해 당신에게 많은 경고를 줄 것입니다.

다른 사람들이 언급했듯이, 이것은 완벽하게 합법적이며 컴파일러에 모호하지 않습니다.

그러나 이것은 혼란이나 찾기 어려운 버그를 유발할 가능성이있는 프로그래밍 언어의 많은 기능 중 하나입니다. 이러한 각 변수에 다른 이름을주는 것은 사소한 일이므로 명확성을 위해 항상 그렇게하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top