问题
Given the following program:
/* 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;
}
On a Mac OS system (Xcode 3.2.3) if I use cc
for compilation using the -std=c99
flag everything seems just right:
nietzsche:problem_1 robert$ cc -std=c99 problem_1.c -o problem_1
nietzsche:problem_1 robert$ ./problem_1
Sum: 233333333166666668
However, if I use c99
to compile it this is what happens:
nietzsche:problem_1 robert$ c99 problem_1.c -o problem_1
nietzsche:problem_1 robert$ ./problem_1
Error: Unsigned Integer Wrapping.
Can you please explain this behavior?
回答1:
c99 is a wrapper of gcc. It exists because POSIX requires it. c99
will generate a 32-bit (i386) binary by default.
cc is a symlink to gcc, so it takes whatever default configuration gcc
has. gcc
produces a binary in native architecture by default, which is x86_64.
unsigned long
is 32-bit long on i386 on OS X, and 64-bit long on x86_64. Therefore, c99
will have a "Unsigned Integer Wrapping", which cc -std=c99
does not.
You could force c99
to generate a 64-bit binary on OS X by the -W 64
flag.
c99 -W 64 proble1.c -o problem_1
(Note: by gcc
I mean the actual gcc binary like i686-apple-darwin10-gcc-4.2.1
.)
回答2:
Under Mac OS X, cc is symlink to gcc (defaults to 64 bit), and c99 is not (defaults to 32bit).
/usr/bin/cc -> gcc-4.2
And they use different default byte-sizes for data types.
/** 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
Quite simply, you are overflowing (aka wrapping) your integer variable when using the c99 compiler.
.PMCD.
来源:https://stackoverflow.com/questions/4182413/what-is-the-difference-between-cc-std-c99-and-c99-on-mac-os