source

"#define for if (false) {} other for"에 사용할 수 있는 것은 무엇입니까?

ittop 2023. 7. 1. 10:00
반응형

"#define for if (false) {} other for"에 사용할 수 있는 것은 무엇입니까?

다른 질문에서, 저는 방금 C 지혜의 작은 진주를 발견했습니다.

#define for if (false) {} else for

이로 인해 MSVC는 상당히 유효한 진술에 대해 "일정한 표현" 경고를 내뱉었습니다.

for (int i = 0; i <= 10; i++) {...}

MSVC가 다음과 같이 확장되기 때문에 불평하는 이유를 이해합니다.

if (false) {} else for (int i = 0; i <= 10; i++) {...}

저는 개발자들이 왜 그 작은 스니펫을 사용하는지 이해할 수 없습니다.생각나는 사람?

이전 버전의 Visual C++(v6.0 및 이전 버전)의 버그를 수정하기 위한 것입니다. C에 Visual C++ 내부에 에 대한 했습니다.for문:

// This compiles in old versions of Visual C++, but it is in fact INVALID C++
for(int i = 0; ...)
{
    ...
}

for(i = 0; ...)
{

}

즉, Visual C++은 다음과 같은 기능을 제공합니다.i루프 외부에 선언된 것처럼 스코프를 사용하면 루프가 완료된 후에도 계속 사용할 수 있습니다.이로 인해 위의 스니펫과 같은 코드가 발생합니다. 많은 호환 컴파일러에서 더많은 러에서일컴파i두 번째 정의에서는 더 이상 범위에 포함되지 않습니다.for 그래서 는 루프, 그서컴는에 대한 를 발행합니다.i정의되지 않음

이 문제를 해결하기 위해 일부 사용자는 이 매크로(또는 매우 유사한 동등한 매크로)를 사용했습니다.

#define for if(0) {} else for

이는 다음을 변경합니다.for다음으로 루프:

if(0)
{
}
else
    for(int i = 0; ...)
    {
        ...
    }

이는 다음과 같습니다.for범위의 위의추수로루여하, 된 변수가 .for루프는 나중에 Visual C++의 버그에 관계없이 범위를 벗어납니다.이렇게 하면 Visual C++ 컴파일러와 표준 호환 컴파일러 모두에서 동일한 코드가 올바르게 컴파일되고 잘못된 코드가 일관되게 컴파일되지 않습니다.

또한 매크로가 대신 그렇게 정의된 경우에도 주의하십시오.

// DO NOT USE
#define for if(1) for

그러면 일부 단순 코드에 대해서는 동일한 영향을 미치지만, 갑자기 다음 코드가 잘못 컴파일됩니다.

if(foo)
    for(...)
    {
        ...
    }
else
    doSomething();

매크로를 확장하면 다음과 같이 됩니다.

if(foo)
    if(1)
        for(...)
        {
            ...
        }
    else
        doSomething();

리고그.else이제 잘못된 것과 일치합니다.if 서그영, 의리사용은한을 사용하는 .if(0) {} elseif(1)이 문제를 방지합니다.

마막으로지,,#define for if(0) {} else for사전 처리기가 현재 정의 중인 매크로를 재귀적으로 대체하지 않으므로 무한 재귀가 발생하지 않습니다.이 경우에는 한 번만 교체할 수 있습니다.

빠른 검색에 따르면 극복되는 것은 MSVC의 버그입니다.

내가 이해하는 바로는

for(int i=0...){...}에 대해}//나중에 동일한 기능의 동일한 스코프 레벨에서for(int i=0...){...}

'i' 오류를 재정의합니다.

for 문이 if 문에 포함되어 있으면 컴파일러는 재정의 오류가 없도록 작동합니다(분명히 'if'의 범위 수준을 해석하지만 'for'는 해석하지 않음).

msvc 컴파일러가 for 문에 선언된 변수의 범위를 기본적으로 잘못 처리하기 때문입니다.이 동작을 방지하려면 마이크로소프트 확장을 해제해야 했고, 이로 인해 ms 헤더가 컴파일되지 않았습니다.

인텔 컴파일러가 여전히 발견하지만 (네, 저는 여전히 vs6를 사용합니다) vs6에서 경고를 유발하지 않는 다른 것을 사용합니다.

#define for switch(0) case 0: default: for

어디서 구했는지는 기억이 안나지만, 제가 발명했는지는 의심스럽습니다 ;-)

다른 답변이 이미 대부분을 말하고 있지만, 사용자가 질문에 답하는지 확인하라는 팝업이 표시됩니다.

효과는 이미 설명되어 있습니다.

그것을 가지고 있는 이유는 C++ 코드를 MSVC에 포트하기 위해서입니다.또는 C++ 코드 플랫폼을 독립적으로 사용하려는 경우에도 매우 유용합니다.예를 들어 Linux/MacOSX에서 개발한 경우 MSVC에서 컴파일하려고 합니다.

그리고 C++ 자체에도 매우 유용합니다.예:

for(std::set<Foo>::iterator i = myset.begin(); i != myset.end(); ++i) {
    // ...
}

for(int i = 0; i < N; ++i) {
    // ...
}

다음 중 하나를 수행하여 이 문제를 해결하는 MSVC 코드를 보았습니다.

for(std::set<Foo>::iterator i1 = myset.begin(); i1 != myset.end(); ++i1) {
    // ...
}

for(int i2 = 0; i2 < N; ++i2) {
    // ...
}

또는:

{for(std::set<Foo>::iterator i = myset.begin(); i != myset.end(); ++i) {
    // ...
}}

{for(int i = 0; i < N; ++i) {
    // ...
}}

두 경우 모두 (imo) 그렇게 좋지 않습니다.그리고 이 #define은 MSVC를 보다 표준적으로 동작시키기 위한 작은 해킹입니다.

언급URL : https://stackoverflow.com/questions/984878/what-is-the-possible-use-for-define-for-if-false-else-for

반응형