2010-11-15 1 views
4

Учитывая следующую программу:В чем разница между `cc -std = c99` и` c99` в Mac OS?

/* Find the sum of all the multiples of 3 or 5 below 1000. */ 

#include <stdio.h> 

unsigned long int method_one(const unsigned long int n); 

int 
main(int argc, char *argv[]) 
{ 
     unsigned long int sum = method_one(1000000000); 
     if (sum != 0) { 
       printf("Sum: %lu\n", sum); 
     } else { 
       printf("Error: Unsigned Integer Wrapping.\n"); 
     } 

     return 0; 
} 

unsigned long int 
method_one(const unsigned long int n) 
{ 
     unsigned long int i; 
     unsigned long int sum = 0; 
     for (i=1; i!=n; ++i) { 
       if (!(i % 3) || !(i % 5)) { 
         unsigned long int tmp_sum = sum; 
         sum += i; 
         if (sum < tmp_sum) 
           return 0; 
       } 
     } 

     return sum; 
} 

В системе Mac OS (Xcode 3.2.3), если я использую cc для компиляции, используя -std=c99 флаг все кажется просто право:

nietzsche:problem_1 robert$ cc -std=c99 problem_1.c -o problem_1 
nietzsche:problem_1 robert$ ./problem_1 
Sum: 233333333166666668 

Однако, если Я использую c99 скомпилировать это то, что происходит:

nietzsche:problem_1 robert$ c99 problem_1.c -o problem_1 
nietzsche:problem_1 robert$ ./problem_1 
Error: Unsigned Integer Wrapping. 

Можете ли вы объяснить это поведение ?

+1

Невозможно использовать 1000000 как пример, который показывает разницу и быстрее вычислять? ;) – kennytm

+1

Вы пробовали выполнить код, скомпилированный с обоими компиляторами? Я полагаю, что 'unsigned long int' 32-бит в одном из компиляторов и 64-битных в другом. –

+0

@KennyTM: Кажется, так, спасибо! –

ответ

11

c99 is a wrapper of gcc. Он существует, потому что POSIX требует его. c99 будет генерировать 32-битный (i386) двоичный файл по умолчанию.

cc is a symlink to gcc, поэтому он принимает любую конфигурацию по умолчанию gcc имеет. gcc по умолчанию создает двоичный файл в собственной архитектуре, который равен x86_64.

unsigned long 32-разрядная версия i386 на OS X и 64-разрядная версия x86_64. Следовательно, c99 будет иметь «Unsigned Integer Wrapping», который cc -std=c99 этого не делает.

Вы можете заставить c99 генерировать 64-битную двоичную информацию на OS X флагом -W 64.

c99 -W 64 proble1.c -o problem_1 

(Примечание: по gcc Я имею в виду фактическое Gcc двоичный как i686-apple-darwin10-gcc-4.2.1.)

+1

Ничего себе, какая невероятно глупая установка. Есть ли причина для этого безумия? –

+0

@R ..: Я не знаю. Может быть, только Apple знает. – kennytm

3

В операционной системе Mac OS X, куб.см является символической ссылкой на НКУ (по умолчанию 64 бит), и c99 не является (по умолчанию 32bit).

/USR/бен/куб.см -> НКУ-4,2

И они используют различные стандартные байт-размеры для типов данных.

 
/** sizeof.c 
*/ 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv) 
{ 
    printf("sizeof(unsigned long int)==%d\n", (int)sizeof(unsigned long int)); 

    return EXIT_SUCCESS; 
} 

cc -std=c99 sizeof.c 
./a.out 
sizeof(unsigned long int)==8 


c99 sizeof.c 
./a.out 
sizeof(unsigned long int)==4 

Проще говоря, вы переполнены (ака оберточную) Ваше целочисленную переменную при использовании C99 компилятор.

.PMCD.