以下のプログラムは、C89モードでコンパイルしたときに「C89」を出力し、C99モードでコンパイルしたときに「C99」をどのように出力しますか?


128

私はこのCプログラムをウェブから見つけました:

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5//**/
    -4.5)));

    return 0;
}

このプログラムの興味深い点は、C89モードでC89コンパイルおよび実行すると印刷され、C99モードでコンパイルおよび実行すると印刷されることC99です。しかし、私はこのプログラムがどのように機能するかを理解することができません。

printf上記のプログラムで2番目の引数がどのように機能するかを説明できますか?


47
ヒント:C ++スタイルの//コメントはC99で導入されました。
Paul R

4
いいトリックですが、で失敗しgccます。なければstd=c99警告を得るでしょう、そしてあなたはそれを無視した場合、gccます、まだ解釈//コメントの開始として(ああ-あなたが使用する必要があります-pedantic。同様に、私はデフォルトでオンになっているがあります。)
usr2564301

3
@Jongwareまあ、私はgcc 4.9.2 C89で明示的に取得しstd=c89ました。
ikh 2015年

60
C99サポートをテストする方法を探しているときに誰かがこれを見つけた場合に備えて。コメントトリック#if __STDC_VERSION__ >= 199901Lではなく、などを使用してください//。=)
Arkku

10
また、C11の「C99」も出力します...
Lundin

回答:


133

C99では- //スタイルのコメントを使用できますが、C89 では使用できません。したがって、翻訳するには:

C99:

 printf("C%d\n",(int)(90-(-4.5     /*Some  comment stuff*/
                         -4.5)));
// Outputs: 99

C89:

printf("C%d\n",(int)(90-(-4.5/      
                         -4.5)));
/* so  we get 90-1 or 89 */

25

行コメント//はC99以降に導入されました。したがって、コードはC89ではこれと同じです。

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5/
-4.5)));

    return 0;
}
/* 90 - (-4.5 / -4.5) = 89 */

C99ではこれに等しい

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5
-4.5)));

    return 0;
}
/* 90 - (-4.5 - 4.5) = 99*/

9

//コメントはC99以降の標準にのみ存在するため、コードは次のコードと同等です。

#include <stdio.h>

int main (void)
{
  int vers;

  #if   __STDC_VERSION__ >= 201112L
    vers = 99; // oops
  #elif __STDC_VERSION__ >= 199901L
    vers = 99;
  #else
    vers = 90;
  #endif

  printf("C%d", vers);

  return 0;
}

正しいコードは次のとおりです。

#include <stdio.h>

int main (void)
{
  int vers;

  #if   __STDC_VERSION__ >= 201112L
    vers = 11;
  #elif __STDC_VERSION__ >= 199901L
    vers = 99;
  #else
    vers = 90;
  #endif

  printf("C%d", vers);

  return 0;
}

あなたの答えの1つずれたエラー、89を印刷することになっているときにどうやって90を得るのですか?
Pimgd

1
@Pimgd C89とC90は同じものです。stackoverflow.com/questions/17206568/...
ランディン

3
同じ意味ですが、同じ文字列ではありません。私の元の質問を待っています。
Pimgd 2015年

@Pimgd上記のコードの目的は、特定の形式の後に文字列を印刷するための人工的なタスクを実行することではありません。目的は、IOCCC外の実際のアプリケーションが、プログラムのコンパイルに使用したCバージョンをどのように出力するかを示すことです。C90は、「C89」または「ANSI-C」よりも使用する方が正しいです。
ランディン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.