В чем разница между `cc -std = c99` и` c99` в Mac OS? - PullRequest
4 голосов
/ 15 ноября 2010

Учитывая следующую программу:

/*  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.

Не могли бы вы объяснить это поведение?

Ответы [ 2 ]

11 голосов
/ 15 ноября 2010

c99 - это оболочка gcc. Это существует, потому что POSIX требует этого. c99 по умолчанию сгенерирует 32-разрядный (i386) двоичный файл.

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

unsigned long имеет 32-разрядную длину на i386 на OS X и 64-разрядную на x86_64. Таким образом, c99 будет иметь «Целочисленную упаковку без знака», а 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.)

3 голосов
/ 15 ноября 2010

В Mac OS X cc - это символическая ссылка на gcc (по умолчанию 64-битная), а c99 - нет (по умолчанию 32-битная).

/ usr / bin / cc -> gcc-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.

...