如何使用旧语法和现代编译器编译C代码?

时间:2013-06-13 18:08:01

标签: c llvm

我在OS X上使用i686-apple-darwin11-llvm-gcc-4.2,我正在尝试从this archive编译各种程序,特别是经典的FitCurves.c,它通过一系列点拟合贝塞尔曲线

http://tog.acm.org/resources/GraphicsGems/

定义了一些void或int函数,但没有返回类型,这会生成警告。

ConcaveScan.c:149:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
compare_ind(u, v) int *u, *v; {return pt[*u].y <= pt[*v].y ? -1 : 1;}

我对此不太确定:有错误

cc -g -Wno-implicit-int -Wreturn-type   -c -o AAPolyScan.o AAPolyScan.c
AAPolyScan.c:106:4: error: non-void function 'drawPolygon' should return a value [-Wreturn-type]
return;                         /* (null polygon) */

据我了解,似乎编译器认为它被隐含地声明为返回int的函数,但该函数返回void,导致错误。从声明返回int的函数到C return是否有意义?我在这里很困惑..

我怎么能很好地编译呢?我不一定无法编译,但警告不是很有用。它是用旧语法编写的,我知道。

2 个答案:

答案 0 :(得分:4)

您可以禁用该警告,因为您不关心它:

-Wno-implicit-int

另外,你确定你正在使用llvm-gcc吗?当我用你的例子进行测试时,我不得不添加-Wall来让gcc说:

$ gcc -Wall -c -o example.o example.c
example.c:8: warning: return type defaults to ‘int’
但是克朗说:

$ clang -c -o example.o example.c
example.c:8:1: warning: type specifier missing, defaults to 'int'
      [-Wimplicit-int]
compare_ind(u, v) int *u, *v; {return pt[*u].y <= pt[*v].y ? -1 : 1;}
^~~~~~~~~~~
1 warning generated.

根本没有任何标记,并且该消息更符合您问题中的警告。在我的机器上:

$ gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cc --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix

答案 1 :(得分:3)

尝试使用-ansi选项,该选项指定符合1989 ANSI C标准(相当于1990 ISO C标准)。旧标准允许隐式int和旧式函数定义。

C99删除了隐式int(但奇怪的是,C99和C11都允许使用旧式函数定义)。

编译器认为它被隐式声明为一个返回int的函数,因为它正好是在ANSI C之前或1999之前的ANSI / ISO c中。​​

但即使使用-ansi,编译器仍可能会警告某个函数定义为返回int(显式或隐式)不返回值。在ANSI-C之前,没有void类型或关键字,并且通常在没有显式返回类型的情况下编写不返回有意义值的函数。旧的编译器不会警告这个常见的习语。相当合理的是,更现代的,因为有更好的方法来实现相同的结果:定义函数void作为返回类型。

关于return;语句的投诉是错误而不是警告,因为从C99开始,return在非void函数中没有表达,或者{在return函数中使用表达式的{1}}实际上是非法的(违反约束)。在C89 / C90中,非空函数中没有值的void是合法的(但如果调用者尝试使用结果,则会导致未定义的行为)。

警告消息包括用于启用它们的选项:

return;

撤消这些选项应禁止警告。指定warning: type specifier missing, defaults to 'int' [-Wimplicit-int] ... error: non-void function 'drawPolygon' should return a value [-Wreturn-type] -ansi也是个好主意; gcc目前默认为-std=c89,但在将来的版本中可能会发生变化。

gnu89

(这是基于我使用gcc 4.7.2的观察结果。我对gcc和gcc-llvm之间的关系并不完全清楚,但他们似乎采用相同的选项。)