鉴于以下计划:
/* 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.
你能解释一下这种行为吗?
答案 0 :(得分:11)
c99
is a wrapper of gcc
。它存在是因为POSIX需要它。 c99
默认会生成32位(i386)二进制文件。
cc
is a symlink to gcc
,因此它需要默认配置gcc
。 gcc
默认情况下在本机体系结构中生成二进制文件,即x86_64。
unsigned long
在OS X上的i386上为32位长,在x86_64上为64位长。因此,c99
将具有“无符号整数换行”,而cc -std=c99
则不会。
您可以强制c99
通过-W 64
标志在OS X上生成64位二进制文件。
c99 -W 64 proble1.c -o problem_1
(注意:gcc
我的意思是实际的gcc二进制文件,如i686-apple-darwin10-gcc-4.2.1
。)
答案 1 :(得分:3)
在Mac OS X下,cc是符号链接到gcc(默认为64位),而c99不是(默认为32位)。
/ usr / bin / cc - &gt; 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。