52

タイプミスの後、次の式 (簡略化) がコンパイルおよび実行されました。

if((1 == 2) || 0 (-4 > 2))
  printf("Hello");

もちろん、0 があってはなりません。

なぜコンパイルされるのですか? また、式の意味は何ですか?

元の(簡略化された)は次のようになります。

if((1 == 2) || (-4 > 2))
  printf("Hello");

これはどれもコンパイルしません:

if((1 == 2) || true (-4 > 2))
  printf("Hello");

if((1 == 2) || 1 (-4 > 2))
  printf("Hello");

if((1 == 2) || null (-4 > 2))
  printf("Hello");
4

6 に答える 6

26

これは、特定の「関数が定義されていない」イディオムをサポートするための Visual C++ 拡張機能のようです。警告 C4353ページから:

// C4353.cpp
// compile with: /W1
void MyPrintf(void){};
#define X 0
#if X
   #define DBPRINT MyPrint
#else
   #define DBPRINT 0   // C4353 expected
#endif
int main(){
    DBPRINT();
}

意図DBPRINTはノーオペレーションです。警告は#define DBPRINT __noop、代わりに VC の__noop拡張機能を使用することを提案しています。

出力のアセンブリ リストを表示すると、デバッグ モードであっても、2 番目の句が省略されていることがわかります。

于 2013-07-25T12:56:41.537 に答える
9

Visual Studio 2012 では、次の警告が表示されます。

警告 C4353: 非標準の拡張子が使用されています: 関数式として定数 0 が使用されています。代わりに '__noop' 関数組み込みを使用してください

式評価のその時点で「操作なし」のアセンブラー命令を挿入するのは非標準的な方法です

于 2013-07-25T12:55:56.373 に答える
8

実際、これはMicrosoft 固有のものです。

デバッグ目的で、__noop組み込みを使用できます。これは、関数とパラメーターが評価されないように指定します。

あなたの場合、Microsoft コンパイラは、同じことを行うために 0 を使用しようとしていると考えています。これが機能する理由ですが、たとえば、VS2012 では警告が表示されます。

warning C4353: nonstandard extension used: constant 0 as function expression.  Use '__noop' function intrinsic instead.

詳細については、http: //msdn.microsoft.com/en-us/library/2a68558f (v=vs.71).aspx を参照してください。

于 2013-07-25T12:58:20.647 に答える
0

おそらく0ここで関数ポインタにキャストされます。明示的なキャストは次のようになります。

if((1 == 2) || ((int (*)(int)) 0) (-4 > 2)) 
      printf("Hello");

0ただし、あなたの例で暗黙的にキャストされる関数については推測できません。

于 2013-07-25T12:55:55.380 に答える