Bagaimana program di bawah ini menghasilkan `C89` saat dikompilasi dalam mode C89 dan` C99` saat dikompilasi dalam mode C99?

128

Saya telah menemukan program C ini dari web:

#include <stdio.h>

int main(){

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

    return 0;
}

Hal yang menarik dengan program ini adalah bahwa ketika dikompilasi dan dijalankan dalam mode C89, ia mencetak C89dan ketika dikompilasi dan dijalankan dalam mode C99, ia mencetak C99. Tetapi saya tidak dapat menemukan cara kerja program ini.

Bisakah Anda menjelaskan bagaimana argumen kedua printfberfungsi pada program di atas?

Spikatrix
sumber
47
Petunjuk: //komentar gaya C ++ diperkenalkan di C99.
Paul R
4
Trik yang bagus - tetapi gagal gcc. Tanpa std=c99Anda akan mendapatkan peringatan, dan jika Anda mengabaikannya, masihgcc akan menafsirkan sebagai awal komentar (ah - Anda harus menggunakan juga. Saya sudah mengaktifkannya secara default.)//-pedantic
usr2564301
3
@ Jongware Yah, saya dapatkan C89dengan eksplisit std=c89di gcc 4.9.2.
ikh
60
Untuk berjaga-jaga seandainya seseorang menemukan ini saat mencari cara untuk menguji dukungan C99; tolong gunakan sesuatu seperti #if __STDC_VERSION__ >= 199901L, bukan //trik komentar. =)
Arkku
10
Ia juga mencetak "C99" untuk C11 ...
Lundin

Jawaban:

133

C99 memungkinkan //komentar gaya, C89 tidak. Jadi, untuk menerjemahkan:

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 */
Paul Rubel
sumber
25

komentar baris //diperkenalkan sejak C99. Karenanya kode Anda sama dengan ini di C89

#include <stdio.h>

int main(){

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

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

dan sama dengan ini di C99

#include <stdio.h>

int main(){

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

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

Karena //komentar hanya ada di C99 dan kemudian standar, kode ini setara dengan yang berikut:

#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;
}

Kode yang benar adalah:

#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;
}
Lundin
sumber
off-by-one error dalam jawaban Anda, bagaimana Anda mendapatkan 90 ketika seharusnya mencetak 89?
Pimgd
1
@Pimgd C89 dan C90 adalah hal yang sama. stackoverflow.com/questions/17206568/…
Lundin
3
Mereka berarti hal yang sama tetapi bukan string yang sama. Berdiri dengan pertanyaan awal saya.
Pimgd
@Pimgd. Tujuan dari kode di atas bukan untuk sate beberapa tugas buatan untuk mencetak string setelah format yang diberikan. Tujuannya adalah untuk menunjukkan bagaimana aplikasi kata nyata di luar IOCCC mencetak versi C yang dikompilasi dengan program. C90 lebih tepat digunakan daripada "C89" atau "ANSI-C".
Lundin